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,139 +1,139 @@
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-cache$
^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/.cache$
-^Tests/Rivet/.*(EE|DIS|LHC|TVT|Star|ISR|SppS)-.*\.in$
+^Tests/Rivet/.*(Rivet|SPS|EHS|Fermilab|EE|DIS|LHC|TVT|Star|ISR|SppS)-.*\.in$
^Tests/plots$
^Tests/Herwig$
^Tests/.*index.html$
Tests/python/LowEnergy-EE.py
Tests/python/LowEnergy-Photon.py
Tests/python/R.py
Tests/python/make_input_files.py
Tests/python/merge-DIS
Tests/python/merge-EE
Tests/python/merge-EE-Gamma
Tests/python/merge-Fixed
Tests/python/merge-GammaGamma
Tests/python/merge-LHC-EW
Tests/python/merge-LHC-Jets
Tests/python/merge-LHC-Photon
Tests/python/merge-Star
Tests/python/merge-TVT-EW
Tests/python/merge-TVT-Jets
Tests/python/merge-TVT-Photon
Tests/python/mergeLowEnergy.py
Tests/python/plot-EE
Tests/python/rivet_check
PDF/SaSPhotonPDF.cc
^Herwig\-
^Models/Feynrules/python/Makefile-FR$
^MatrixElement/Matchbox/External/MadGraph/mg2herwig$
MatrixElement/Matchbox/External/GoSam/gosam2herwig.py
^MatrixElement/Matchbox/Scales/MatchboxScale.cc$
Sampling/herwig-mergegrids.py
^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/MatchboxMergingDefaults.in
^src/Matchbox/done-all-links$
^src/snippets/done-all-links$
^Utilities/XML/xml_test$
^Utilities/utilities_test$
^Utilities/versionstring.h$
^MatrixElement/Matchbox/External/MadGraph/mg2herwig.py$
test\.(log|trs)$
test-suite\.log$
^Config/test-driver$
param_card\.dat$
__all.cc$
.ccR$
^tmp/*
PDF/stamp-h2
Tests/anatohepmc.txt
Tests/hepmctoana.txt
diff --git a/Analysis/CrossSectionAnalysis.cc b/Analysis/CrossSectionAnalysis.cc
--- a/Analysis/CrossSectionAnalysis.cc
+++ b/Analysis/CrossSectionAnalysis.cc
@@ -1,101 +1,99 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the CrossSectionAnalysis class.
//
#include "CrossSectionAnalysis.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Handlers/EventHandler.h"
#include "ThePEG/Handlers/StandardEventHandler.h"
#include "Herwig/Sampling/GeneralSampler.h"
#include "Herwig/Utilities/XML/ElementIO.h"
using namespace Herwig;
CrossSectionAnalysis::CrossSectionAnalysis() {}
-CrossSectionAnalysis::~CrossSectionAnalysis() {}
-
#ifndef LWH_AIAnalysisFactory_H
#ifndef LWH
#define LWH ThePEGLWH
#endif
#include "ThePEG/Analysis/LWH/AnalysisFactory.h"
#endif
void CrossSectionAnalysis::dofinish() {
AnalysisHandler::dofinish();
Ptr<StandardEventHandler>::tptr seh =
dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(generator()->eventHandler());
Ptr<GeneralSampler>::tptr sampler =
dynamic_ptr_cast<Ptr<GeneralSampler>::tptr>(seh->sampler());
unsigned long attemptedPoints = sampler->attempts();
double sumOfWeights = sampler->sumWeights();
double sumOfSquaredWeights = sampler->sumWeights2();
CrossSection maxXSection = sampler->maxXSec();
XML::Element elem(XML::ElementTypes::Element,"Run");
elem.appendAttribute("name",generator()->runName());
elem.appendAttribute("attemptedPoints",attemptedPoints);
elem.appendAttribute("sumOfWeights",sumOfWeights*maxXSection/picobarn);
elem.appendAttribute("sumOfSquaredWeights",sumOfSquaredWeights*sqr(maxXSection/picobarn));
XML::Element xhistos(XML::ElementTypes::Element,"Histograms");
elem.append(xhistos);
string fname = generator()->filename() + string("-") + name() + string(".xml");
ofstream runXML(fname.c_str());
runXML << setprecision(16);
XML::ElementIO::put(elem,runXML);
}
IBPtr CrossSectionAnalysis::clone() const {
return new_ptr(*this);
}
IBPtr CrossSectionAnalysis::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void CrossSectionAnalysis::persistentOutput(PersistentOStream &) const {}
void CrossSectionAnalysis::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<CrossSectionAnalysis,AnalysisHandler>
describeHerwigCrossSectionAnalysis("Herwig::CrossSectionAnalysis", "HwJetsAnalysis.so");
void CrossSectionAnalysis::Init() {
static ClassDocumentation<CrossSectionAnalysis> documentation
("There is no documentation for the CrossSectionAnalysis class");
}
diff --git a/Analysis/CrossSectionAnalysis.h b/Analysis/CrossSectionAnalysis.h
--- a/Analysis/CrossSectionAnalysis.h
+++ b/Analysis/CrossSectionAnalysis.h
@@ -1,105 +1,97 @@
// -*- C++ -*-
#ifndef Herwig_CrossSectionAnalysis_H
#define Herwig_CrossSectionAnalysis_H
//
// This is the declaration of the CrossSectionAnalysis class.
//
#include "ThePEG/Handlers/AnalysisHandler.h"
namespace Herwig {
using namespace ThePEG;
/**
* Here is the documentation of the CrossSectionAnalysis class.
*
* @see \ref CrossSectionAnalysisInterfaces "The interfaces"
* defined for CrossSectionAnalysis.
*/
class CrossSectionAnalysis: public AnalysisHandler {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
CrossSectionAnalysis();
- /**
- * The destructor.
- */
- virtual ~CrossSectionAnalysis();
- //@}
-
protected:
/**
* Finalize this object. Called in the run phase just after a
* run has ended. Used eg. to write out statistics.
*/
virtual void dofinish();
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.
*/
CrossSectionAnalysis & operator=(const CrossSectionAnalysis &) = delete;
};
}
#endif /* Herwig_CrossSectionAnalysis_H */
diff --git a/Analysis/HJetsAnalysis.cc b/Analysis/HJetsAnalysis.cc
--- a/Analysis/HJetsAnalysis.cc
+++ b/Analysis/HJetsAnalysis.cc
@@ -1,127 +1,125 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the HJetsAnalysis class.
//
#include "HJetsAnalysis.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
HJetsAnalysis::HJetsAnalysis() {}
-HJetsAnalysis::~HJetsAnalysis() {}
-
IBPtr HJetsAnalysis::clone() const {
return new_ptr(*this);
}
IBPtr HJetsAnalysis::fullclone() const {
return new_ptr(*this);
}
void HJetsAnalysis::reconstructHardObjects(ParticleVector& parts) {
ParticleVector::iterator higgs = parts.begin();
for ( ; higgs != parts.end(); ++higgs ) {
if ( (**higgs).id() == ParticleID::h0 )
break;
}
if ( higgs == parts.end() )
throw Exception() << "No Higgs found in HJetsAnalysis"
<< Exception::abortnow;
hardObjectMomentum("h") = (**higgs).momentum();
parts.erase(higgs);
}
void HJetsAnalysis::analyzeSpecial(long id, double weight) {
if ( nJets() < 2 )
return;
higgsYStar().count(Statistics::EventContribution(yStar(jetMomentum(1),jetMomentum(2),hardObjectMomentum("h")),weight,0.1),id);
if ( nJets() > 2 )
thirdJetYStar().count(Statistics::EventContribution(yStar(jetMomentum(1),jetMomentum(2),jetMomentum(3)),weight,0.1),id);
if ( nJets() > 3 )
fourthJetYStar().count(Statistics::EventContribution(yStar(jetMomentum(1),jetMomentum(2),jetMomentum(4)),weight,0.1),id);
if ( nJets() > 1 ) {
LorentzMomentum p12 = jetMomentum(1) + jetMomentum(2);
double dphi = JetsPlusAnalysis::PairProperties::dPhi(p12,hardObjectMomentum("h"));
jet12HiggsDeltaPhi().count(Statistics::EventContribution(dphi,weight,0.1),id);
// Jeppe delta phi
double minRap = jetMomentum(1).rapidity();
double maxRap = minRap;
for ( unsigned int k = 2; k <= nJets(); ++k ) {
double yjet = jetMomentum(k).rapidity();
minRap = min(minRap,yjet);
maxRap = max(maxRap,yjet);
}
double hrap = hardObjectMomentum("h").rapidity();
if ( minRap < hrap && hrap < maxRap ) {
LorentzMomentum pLeft, pRight;
for ( unsigned int k = 1; k <= nJets(); ++k ) {
const LorentzMomentum& pjet = jetMomentum(k);
if ( pjet.rapidity() < hrap )
pLeft += pjet;
else
pRight += pjet;
}
double jeppedphi = JetsPlusAnalysis::PairProperties::dPhi(pLeft,pRight);
jeppeDeltaPhi().count(Statistics::EventContribution(jeppedphi,weight,0.1),id);
}
}
}
void HJetsAnalysis::finalize(XML::Element& xhistos) {
if ( !theHiggsYStar.bins().empty() ) {
theHiggsYStar.finalize();
xhistos.append(theHiggsYStar.toXML());
}
if ( !theThirdJetYStar.bins().empty() ) {
theThirdJetYStar.finalize();
xhistos.append(theThirdJetYStar.toXML());
}
if ( !theFourthJetYStar.bins().empty() ) {
theFourthJetYStar.finalize();
xhistos.append(theFourthJetYStar.toXML());
}
if ( !theJet12HiggsDeltaPhi.bins().empty() ) {
theJet12HiggsDeltaPhi.finalize();
xhistos.append(theJet12HiggsDeltaPhi.toXML());
}
if ( !theJeppeDeltaPhi.bins().empty() ) {
theJeppeDeltaPhi.finalize();
xhistos.append(theJeppeDeltaPhi.toXML());
}
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void HJetsAnalysis::persistentOutput(PersistentOStream &) const {}
void HJetsAnalysis::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<HJetsAnalysis,Herwig::JetsPlusAnalysis>
describeHerwigHJetsAnalysis("Herwig::HJetsAnalysis", "JetCuts.so HwJetsAnalysis.so");
void HJetsAnalysis::Init() {
static ClassDocumentation<HJetsAnalysis> documentation
("There is no documentation for the HJetsAnalysis class");
}
diff --git a/Analysis/HJetsAnalysis.h b/Analysis/HJetsAnalysis.h
--- a/Analysis/HJetsAnalysis.h
+++ b/Analysis/HJetsAnalysis.h
@@ -1,212 +1,204 @@
// -*- C++ -*-
#ifndef Herwig_HJetsAnalysis_H
#define Herwig_HJetsAnalysis_H
//
// This is the declaration of the HJetsAnalysis class.
//
#include "Herwig/Analysis/JetsPlusAnalysis.h"
namespace Herwig {
using namespace ThePEG;
/**
* Here is the documentation of the HJetsAnalysis class.
*
* @see \ref HJetsAnalysisInterfaces "The interfaces"
* defined for HJetsAnalysis.
*/
class HJetsAnalysis: public Herwig::JetsPlusAnalysis {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
HJetsAnalysis();
- /**
- * The destructor.
- */
- virtual ~HJetsAnalysis();
- //@}
-
public:
/**
* Reconstruct the desired electroweak objects and fill the
* respective momenta. Remove the reconstructed particles from the
* list.
*/
virtual void reconstructHardObjects(ParticleVector&);
protected:
/**
* Perform any additional analysis required
*/
virtual void analyzeSpecial(long id, double weight);
/**
* Append any additional histograms to the given histogram element
*/
virtual void finalize(XML::Element&);
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:
/**
* Relative rapidity of the Higgs between the first two jets
*/
Statistics::Histogram theHiggsYStar;
/**
* Relative rapidity of the third jet between the first two jets
*/
Statistics::Histogram theThirdJetYStar;
/**
* Relative rapidity of the fourth jet between the first two jets
*/
Statistics::Histogram theFourthJetYStar;
/**
* Delta phi between the Higgs and the two-jet system
*/
Statistics::Histogram theJet12HiggsDeltaPhi;
/**
* Jeppe's delta phi
*/
Statistics::Histogram theJeppeDeltaPhi;
protected:
/**
* Calculate ystar given two jets and object of interest
*/
double yStar(const LorentzMomentum& jet1, const LorentzMomentum& jet2,
const LorentzMomentum& obj) const {
double y1 = jet1.rapidity();
double y2 = jet2.rapidity();
double res =
obj.rapidity() - 0.5*(y1+y2);
return res/(y1-y2);
}
/**
* Relative rapidity of the Higgs between the first two jets
*/
Statistics::Histogram& higgsYStar() {
if ( !theHiggsYStar.bins().empty() )
return theHiggsYStar;
return theHiggsYStar =
Statistics::Histogram("HiggsYStar",Statistics::Histogram::regularBinEdges(-6,6,120),false,false);
}
/**
* Relative rapidity of the third jet between the first two jets
*/
Statistics::Histogram& thirdJetYStar() {
if ( !theThirdJetYStar.bins().empty() )
return theThirdJetYStar;
return theThirdJetYStar =
Statistics::Histogram("Jet3YStar",Statistics::Histogram::regularBinEdges(-6,6,120),false,false);
}
/**
* Relative rapidity of the fourth jet between the first two jets
*/
Statistics::Histogram& fourthJetYStar() {
if ( !theFourthJetYStar.bins().empty() )
return theFourthJetYStar;
return theFourthJetYStar =
Statistics::Histogram("Jet4YStar",Statistics::Histogram::regularBinEdges(-6,6,120),false,false);
}
/**
* Delta phi between the Higgs and the two-jet system
*/
Statistics::Histogram& jet12HiggsDeltaPhi() {
if ( !theJet12HiggsDeltaPhi.bins().empty() )
return theJet12HiggsDeltaPhi;
return theJet12HiggsDeltaPhi =
Statistics::Histogram("Jet12hDeltaPhi",
Statistics::Histogram::regularBinEdges(-Constants::pi,Constants::pi,32),
make_pair(-Constants::pi,Constants::pi));
}
/**
* Delta phi between the Higgs and the two-jet system
*/
Statistics::Histogram& jeppeDeltaPhi() {
if ( !theJeppeDeltaPhi.bins().empty() )
return theJeppeDeltaPhi;
return theJeppeDeltaPhi =
Statistics::Histogram("JeppeDeltaPhi",
Statistics::Histogram::regularBinEdges(-Constants::pi,Constants::pi,32),
make_pair(-Constants::pi,Constants::pi));
}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
HJetsAnalysis & operator=(const HJetsAnalysis &) = delete;
};
}
#endif /* Herwig_HJetsAnalysis_H */
diff --git a/Analysis/JetsPlusAnalysis.cc b/Analysis/JetsPlusAnalysis.cc
--- a/Analysis/JetsPlusAnalysis.cc
+++ b/Analysis/JetsPlusAnalysis.cc
@@ -1,363 +1,359 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the JetsPlusAnalysis class.
//
#include "JetsPlusAnalysis.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/SubProcess.h"
#include "ThePEG/EventRecord/SubProcessGroup.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Handlers/EventHandler.h"
#include "ThePEG/Handlers/StandardEventHandler.h"
#include "Herwig/Sampling/GeneralSampler.h"
#include "Herwig/Utilities/XML/ElementIO.h"
using namespace Herwig;
JetsPlusAnalysis::JetsPlusAnalysis()
: theIsShowered(false) {}
-JetsPlusAnalysis::~JetsPlusAnalysis() {}
-
-
-
#ifndef LWH_AIAnalysisFactory_H
#ifndef LWH
#define LWH ThePEGLWH
#endif
#include "ThePEG/Analysis/LWH/AnalysisFactory.h"
#endif
struct SortPt {
inline bool operator()(const LorentzMomentum& a,
const LorentzMomentum& b) const {
return a.perp() > b.perp();
}
};
void JetsPlusAnalysis::reconstructJets(const ParticleVector& parts) {
tcPDVector outType;
vector<LorentzMomentum> outMomenta;
for ( ParticleVector::const_iterator p = parts.begin();
p != parts.end(); ++p ) {
outType.push_back((**p).dataPtr());
outMomenta.push_back((**p).momentum());
}
jetFinder()->cluster(outType, outMomenta,
tcCutsPtr(), tcPDPtr(),tcPDPtr());
sort(outMomenta.begin(),outMomenta.end(),SortPt());
for ( vector<Ptr<JetRegion>::ptr>::iterator j =
theJetRegions.begin(); j != theJetRegions.end(); ++j )
(**j).reset();
for ( size_t k = 0; k < outMomenta.size(); ++k ) {
for ( vector<Ptr<JetRegion>::ptr>::const_iterator r = jetRegions().begin();
r != jetRegions().end(); ++r ) {
if ( (**r).matches(tCutsPtr(),k+1,outMomenta[k])) {
jetMomentum(k+1) = outMomenta[k];
break;
}
}
}
}
void JetsPlusAnalysis::analyze(ParticleVector& parts, long id, double weight) {
clear();
reconstructHardObjects(parts);
reconstructJets(parts);
for ( map<string,LorentzMomentum>::const_iterator h = theHardObjects.begin();
h != theHardObjects.end(); ++h ) {
hardObjectProperties(h->first).count(h->second,weight,id);
map<string,LorentzMomentum>::const_iterator g = h; ++g;
for ( ; g != theHardObjects.end(); ++g ) {
hardPairProperties(h->first,g->first).count(h->second,g->second,weight,id);
}
}
unsigned int njets = 0;
Energy jetSummedPerp = ZERO;
double jetSummedRapidity = 0.0;
double jetSummedPhi = 0.0;
Energy jetSummedM = ZERO;
nJetsInclusive().count(Statistics::EventContribution(njets,weight,0.0),id);
if ( njets == theJets.size() )
nJetsExclusive().count(Statistics::EventContribution(njets,weight,0.0),id);
for ( map<unsigned int,LorentzMomentum>::const_iterator h = theJets.begin();
h != theJets.end(); ++h ) {
njets += 1;
jetProperties(h->first).count(h->second,weight,id);
jetInclusiveProperties().count(h->second,weight,id);
nJetsInclusive().count(Statistics::EventContribution(njets,weight,0.0),id);
if ( njets == theJets.size() ) {
exclusiveJetProperties(h->first).count(h->second,weight,id);
nJetsExclusive().count(Statistics::EventContribution(njets,weight,0.0),id);
}
jetSummedPerp += h->second.perp();
jetSummedRapidity += h->second.rapidity();
jetSummedPhi += h->second.phi();
jetSummedM += h->second.m();
map<unsigned int,LorentzMomentum>::const_iterator g = h; ++g;
for ( ; g != theJets.end(); ++g ) {
jetPairProperties(h->first,g->first).count(h->second,g->second,weight,id);
map<unsigned int,LorentzMomentum>::const_iterator g1 = g; ++g1;
for ( ; g1 != theJets.end(); ++g1 ) {
LorentzMomentum p123 =
h->second + g->second + g1->second;
threeJetProperties(h->first,g->first,g1->first).count(p123,weight,id);
map<unsigned int,LorentzMomentum>::const_iterator g2 = g1; ++g2;
for ( ; g2 != theJets.end(); ++g2 ) {
LorentzMomentum p1234 =
h->second + g->second + g1->second + g2->second;
fourJetProperties(h->first,g->first,g1->first,g2->first).count(p1234,weight,id);
}
}
}
}
if ( njets > 0 )
jetSummedProperties().count(jetSummedPerp,jetSummedRapidity,
jetSummedPhi,jetSummedM,
weight,id);
if ( njets > 0 )
jetAverageProperties().count(jetSummedPerp/njets,jetSummedRapidity/njets,
jetSummedPhi/njets,jetSummedM/njets,
weight,id);
for ( map<string,LorentzMomentum>::const_iterator h = theHardObjects.begin();
h != theHardObjects.end(); ++h ) {
for ( map<unsigned int,LorentzMomentum>::const_iterator g = theJets.begin();
g != theJets.end(); ++g ) {
jetHardPairProperties(g->first,h->first).count(g->second,h->second,weight,id);
}
}
analyzeSpecial(id,weight);
}
void JetsPlusAnalysis::analyze(tEventPtr event, long ieve, int, int) {
// doing nothing
// AnalysisHandler::analyze(event, ieve, loop, state);
Ptr<StandardEventHandler>::tptr seh =
dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(generator()->eventHandler());
Ptr<GeneralSampler>::tptr sampler =
dynamic_ptr_cast<Ptr<GeneralSampler>::tptr>(seh->sampler());
double norm = sampler->maxXSec()/picobarn;
if ( !theIsShowered ) {
tSubProPtr sub = event->primarySubProcess();
Ptr<SubProcessGroup>::tptr grp =
dynamic_ptr_cast<Ptr<SubProcessGroup>::tptr>(sub);
ParticleVector hfs = sub->outgoing();
analyze(hfs,ieve,norm*event->weight()*sub->groupWeight());
if ( grp ) {
for ( SubProcessVector::const_iterator s = grp->dependent().begin();
s != grp->dependent().end(); ++s ) {
ParticleVector fs = (**s).outgoing();
analyze(fs,ieve,norm*event->weight()*(**s).groupWeight());
}
}
} else {
ParticleVector fs;
event->getFinalState(fs);
analyze(fs,ieve,norm*event->weight());
}
}
void JetsPlusAnalysis::dofinish() {
AnalysisHandler::dofinish();
Ptr<StandardEventHandler>::tptr seh =
dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(generator()->eventHandler());
Ptr<GeneralSampler>::tptr sampler =
dynamic_ptr_cast<Ptr<GeneralSampler>::tptr>(seh->sampler());
unsigned long attemptedPoints = sampler->attempts();
double sumOfWeights = sampler->sumWeights();
double sumOfSquaredWeights = sampler->sumWeights2();
CrossSection maxXSection = sampler->maxXSec();
XML::Element elem(XML::ElementTypes::Element,"Run");
elem.appendAttribute("name",generator()->runName());
elem.appendAttribute("attemptedPoints",attemptedPoints);
elem.appendAttribute("sumOfWeights",sumOfWeights*maxXSection/picobarn);
elem.appendAttribute("sumOfSquaredWeights",sumOfSquaredWeights*sqr(maxXSection/picobarn));
XML::Element xhistos(XML::ElementTypes::Element,"Histograms");
for ( map<string,ObjectProperties>::iterator h = theHardObjectProperties.begin();
h != theHardObjectProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<unsigned int,ObjectProperties>::iterator h = theJetProperties.begin();
h != theJetProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<unsigned int,ObjectProperties>::iterator h = theExclusiveJetProperties.begin();
h != theExclusiveJetProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
if ( !theJetInclusiveProperties.pt.bins().empty() ) {
theJetInclusiveProperties.finalize(xhistos);
}
if ( !theJetSummedProperties.pt.bins().empty() ) {
theJetSummedProperties.finalize(xhistos);
}
if ( !theJetAverageProperties.pt.bins().empty() ) {
theJetAverageProperties.finalize(xhistos);
}
if ( !theNJetsInclusive.bins().empty() ) {
theNJetsInclusive.finalize();
xhistos.append(theNJetsInclusive.toXML());
}
if ( !theNJetsExclusive.bins().empty() ) {
theNJetsExclusive.finalize();
xhistos.append(theNJetsExclusive.toXML());
}
for ( map<pair<string,string>,PairProperties>::iterator h = theHardPairProperties.begin();
h != theHardPairProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<pair<unsigned int,unsigned int>,PairProperties>::iterator h = theJetPairProperties.begin();
h != theJetPairProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<pair<unsigned int,string>,PairProperties>::iterator h = theJetHardPairProperties.begin();
h != theJetHardPairProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int>,ObjectProperties>::iterator h =
theThreeJetProperties.begin(); h != theThreeJetProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties>::iterator h =
theFourJetProperties.begin(); h != theFourJetProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
finalize(xhistos);
elem.append(xhistos);
string fname = generator()->filename() + string("-") + name() + string(".xml");
ofstream runXML(fname.c_str());
runXML << setprecision(16);
XML::ElementIO::put(elem,runXML);
}
IBPtr JetsPlusAnalysis::clone() const {
return new_ptr(*this);
}
IBPtr JetsPlusAnalysis::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void JetsPlusAnalysis::persistentOutput(PersistentOStream & os) const {
os << theIsShowered << theJetFinder << theJetRegions;
}
void JetsPlusAnalysis::persistentInput(PersistentIStream & is, int) {
is >> theIsShowered >> theJetFinder >> theJetRegions;
}
// *** 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<JetsPlusAnalysis,AnalysisHandler>
describeHerwigJetsPlusAnalysis("Herwig::JetsPlusAnalysis", "JetCuts.so HwJetsAnalysis.so");
void JetsPlusAnalysis::Init() {
static ClassDocumentation<JetsPlusAnalysis> documentation
("There is no documentation for the JetsPlusAnalysis class");
static Reference<JetsPlusAnalysis,JetFinder> interfaceJetFinder
("JetFinder",
"",
&JetsPlusAnalysis::theJetFinder, false, false, true, false, false);
static RefVector<JetsPlusAnalysis,JetRegion> interfaceJetRegions
("JetRegions",
"",
&JetsPlusAnalysis::theJetRegions, -1, false, false, true, false, false);
static Switch<JetsPlusAnalysis,bool> interfaceIsShowered
("IsShowered",
"",
&JetsPlusAnalysis::theIsShowered, false, false, false);
static SwitchOption interfaceIsShoweredYes
(interfaceIsShowered,
"Yes",
"",
true);
static SwitchOption interfaceIsShoweredNo
(interfaceIsShowered,
"No",
"",
false);
}
diff --git a/Analysis/JetsPlusAnalysis.h b/Analysis/JetsPlusAnalysis.h
--- a/Analysis/JetsPlusAnalysis.h
+++ b/Analysis/JetsPlusAnalysis.h
@@ -1,659 +1,651 @@
// -*- C++ -*-
#ifndef Herwig_JetsPlusAnalysis_H
#define Herwig_JetsPlusAnalysis_H
//
// This is the declaration of the JetsPlusAnalysis class.
//
#include "ThePEG/Handlers/AnalysisHandler.h"
#include "ThePEG/Cuts/JetFinder.h"
#include "ThePEG/Cuts/JetRegion.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Utilities/Statistics/Histogram.h"
namespace Herwig {
using namespace ThePEG;
/**
* Here is the documentation of the JetsPlusAnalysis class.
*
* @see \ref JetsPlusAnalysisInterfaces "The interfaces"
* defined for JetsPlusAnalysis.
*/
class JetsPlusAnalysis: public AnalysisHandler {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
JetsPlusAnalysis();
- /**
- * The destructor.
- */
- virtual ~JetsPlusAnalysis();
- //@}
-
public:
/** @name Virtual functions required by the AnalysisHandler class. */
//@{
/**
* Analyze a given Event. Note that a fully generated event
* may be presented several times, if it has been manipulated in
* between. The default version of this function will call transform
* to make a lorentz transformation of the whole event, then extract
* all final state particles and call analyze(tPVector) of this
* analysis object and those of all associated analysis objects. The
* default version will not, however, do anything on events which
* have not been fully generated, or have been manipulated in any
* way.
* @param event pointer to the Event to be analyzed.
* @param ieve the event number.
* @param loop the number of times this event has been presented.
* If negative the event is now fully generated.
* @param state a number different from zero if the event has been
* manipulated in some way since it was last presented.
*/
virtual void analyze(tEventPtr event, long ieve, int loop, int state);
//@}
protected:
/**
* Analyze one subprocess, given the event number it belongs to
*/
void analyze(ParticleVector&, long, double);
/**
* Clear the hard objects and jets for the next event
*/
void clear() {
theHardObjects.clear();
theJets.clear();
}
/**
* Reconstruct the desired electroweak objects and fill the
* respective momenta. Remove the reconstructed particles from the
* list.
*/
virtual void reconstructHardObjects(ParticleVector&) {}
/**
* Set the momentum of the indicated electroweak object.
*/
LorentzMomentum& hardObjectMomentum(const string& id) {
return theHardObjects[id];
}
/**
* Reconstruct the jets and fill the respective momenta.
*/
virtual void reconstructJets(const ParticleVector&);
/**
* The jet finder to use
*/
Ptr<JetFinder>::tptr jetFinder() const {
return theJetFinder;
}
/**
* The jet regions to match.
*/
const vector<Ptr<JetRegion>::ptr>& jetRegions() const { return theJetRegions; }
/**
* Return the number of matched jets
*/
unsigned int nJets() const { return theJets.size(); }
/**
* Set the momentum of the indicated jet.
*/
LorentzMomentum& jetMomentum(const unsigned int id) {
return theJets[id];
}
protected:
/**
* Finalize this object. Called in the run phase just after a
* run has ended. Used eg. to write out statistics.
*/
virtual void dofinish();
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:
/**
* Collection of object histograms; ranges are adjusted to the
* maximum, so range constraints and rebinning can be applied later.
*/
struct ObjectProperties {
/**
* Transverse momentum
*/
Statistics::Histogram pt;
Statistics::Histogram pt_logx;
/**
* Rapidity
*/
Statistics::Histogram y;
/**
* Azimuth
*/
Statistics::Histogram phi;
/**
* Mass
*/
Statistics::Histogram mass;
/**
* Default constructor
*/
ObjectProperties() {}
/**
* Construct given Ecm
*/
ObjectProperties(const string& name, Energy)
: pt(name + "Pt",Statistics::Histogram::regularBinEdges(0,1000,1000),true,false),
pt_logx(name + "PtLogX",Statistics::Histogram::logBinEdges(0.1,1000,1000),true,false),
y(name + "Y",Statistics::Histogram::regularBinEdges(-6,6,120),false,false),
phi(name + "Phi",Statistics::Histogram::regularBinEdges(-Constants::pi,Constants::pi,32),
make_pair(-Constants::pi,Constants::pi)),
mass(name + "Mass",Statistics::Histogram::regularBinEdges(0,1000,1000),true,false) {}
/**
* Count given momentum, weight and id
*/
void count(const LorentzMomentum& p, double weight, unsigned int id) {
pt.count(Statistics::EventContribution(p.perp()/GeV,weight,1.),id);
pt_logx.count(Statistics::EventContribution(p.perp()/GeV,weight,1.),id);
y.count(Statistics::EventContribution(p.rapidity(),weight,0.1),id);
phi.count(Statistics::EventContribution(p.phi(),weight,0.1),id);
mass.count(Statistics::EventContribution(p.m()/GeV,weight,1.),id);
}
/**
* Count given momentum components, weight and id
*/
void count(Energy perp, double rapidity,
double xphi, Energy m,
double weight, unsigned int id) {
pt.count(Statistics::EventContribution(perp/GeV,weight,1.),id);
pt_logx.count(Statistics::EventContribution(perp/GeV,weight,1.),id);
y.count(Statistics::EventContribution(rapidity,weight,0.1),id);
phi.count(Statistics::EventContribution(xphi,weight,0.1),id);
mass.count(Statistics::EventContribution(m/GeV,weight,1.),id);
}
/**
* Convert to XML
*/
void finalize(XML::Element& elem) {
pt.finalize(); elem.append(pt.toXML());
pt_logx.finalize(); elem.append(pt_logx.toXML());
y.finalize(); elem.append(y.toXML());
phi.finalize(); elem.append(phi.toXML());
mass.finalize(); elem.append(mass.toXML());
}
};
/**
* Collection of pair histograms; ranges are adjusted to the
* maximum, so range constraints and rebinning can be applied later.
*/
struct PairProperties
: public ObjectProperties {
/**
* Calculate deltaPhi
*/
static double dPhi(const LorentzMomentum& a,
const LorentzMomentum& b){
double phi1 = a.phi();
double phi2 = b.phi();
double diff=phi1-phi2;
if(diff<-Constants::pi){
diff+=(2.0*Constants::pi);
}
else if (diff>Constants::pi){
diff-=(2.0*Constants::pi);
}
return diff;
}
/**
* Calculate deltaY
*/
static double dY(const LorentzMomentum& a,
const LorentzMomentum& b){
return abs(a.rapidity()-b.rapidity());
}
/**
* Calculate deltaR
*/
static double dR(const LorentzMomentum& a,
const LorentzMomentum& b){
return sqrt(sqr(dPhi(a,b))+sqr(dY(a,b)));
}
/**
* Calculate ydoty
*/
static double yy(const LorentzMomentum& a,
const LorentzMomentum& b){
double ya = a.rapidity();
double yb = b.rapidity();
double yres = sqrt(abs(ya*yb));
return ya*yb < 0. ? -yres : yres;
}
/**
* Delta y
*/
Statistics::Histogram deltaY;
/**
* Delta phi
*/
Statistics::Histogram deltaPhi;
/**
* Delta phi
*/
Statistics::Histogram deltaR;
/**
* Product of the rapidities
*/
Statistics::Histogram yDotY;
/**
* Default constructor
*/
PairProperties()
: ObjectProperties() {}
/**
* Construct given Ecm
*/
PairProperties(const string& name, Energy ecm)
: ObjectProperties(name,ecm),
deltaY(name + "DeltaY",Statistics::Histogram::regularBinEdges(0,6,60),true,false),
deltaPhi(name + "DeltaPhi",Statistics::Histogram::regularBinEdges(-Constants::pi,Constants::pi,32),
make_pair(-Constants::pi,Constants::pi)),
deltaR(name + "DeltaR",Statistics::Histogram::regularBinEdges(0,10,100),true,false),
yDotY(name + "YDotY",Statistics::Histogram::regularBinEdges(-6,6,120),false,false) {}
/**
* Count given momentum, weight and id
*/
void count(const LorentzMomentum& p, const LorentzMomentum& q, double weight, unsigned int id) {
ObjectProperties::count(p+q,weight,id);
deltaY.count(Statistics::EventContribution(dY(p,q),weight,0.1),id);
deltaPhi.count(Statistics::EventContribution(dPhi(p,q),weight,0.1),id);
deltaR.count(Statistics::EventContribution(dR(p,q),weight,0.1),id);
yDotY.count(Statistics::EventContribution(yy(p,q),weight,0.1),id);
}
/**
* Convert to XML
*/
void finalize(XML::Element& elem) {
ObjectProperties::finalize(elem);
deltaY.finalize(); elem.append(deltaY.toXML());
deltaPhi.finalize(); elem.append(deltaPhi.toXML());
deltaR.finalize(); elem.append(deltaR.toXML());
yDotY.finalize(); elem.append(yDotY.toXML());
}
};
private:
/**
* Switch between fixed order and showered
*/
bool theIsShowered;
/**
* The jet finder to use
*/
Ptr<JetFinder>::ptr theJetFinder;
/**
* The jet regions to match.
*/
vector<Ptr<JetRegion>::ptr> theJetRegions;
/**
* The reconstructed hard objects.
*/
map<string,LorentzMomentum> theHardObjects;
/**
* The reconstructed jets
*/
map<unsigned int,LorentzMomentum> theJets;
/**
* Hard object properties
*/
map<string,ObjectProperties> theHardObjectProperties;
/**
* Jet properties
*/
map<unsigned int,ObjectProperties> theJetProperties;
/**
* Exclusive jet properties
*/
map<unsigned int,ObjectProperties> theExclusiveJetProperties;
/**
* Jet-inclusive properties
*/
ObjectProperties theJetInclusiveProperties;
/**
* Jet-summed properties
*/
ObjectProperties theJetSummedProperties;
/**
* Jet-average properties
*/
ObjectProperties theJetAverageProperties;
/**
* Inclusive jet multiplicities
*/
Statistics::Histogram theNJetsInclusive;
/**
* Exclusive jet multiplicities
*/
Statistics::Histogram theNJetsExclusive;
/**
* Hard object pair properties
*/
map<pair<string,string>,PairProperties> theHardPairProperties;
/**
* Jet pair properties
*/
map<pair<unsigned int,unsigned int>,PairProperties> theJetPairProperties;
/**
* Jet/hard pair properties
*/
map<pair<unsigned int,string>,PairProperties> theJetHardPairProperties;
/**
* Trijet properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int>,ObjectProperties> theThreeJetProperties;
/**
* Fourjet properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties> theFourJetProperties;
protected:
/**
* Hard object properties
*/
ObjectProperties& hardObjectProperties(const string& id) {
map<string,ObjectProperties>::iterator h =
theHardObjectProperties.find(id);
if ( h != theHardObjectProperties.end() )
return h->second;
return
theHardObjectProperties[id] =
ObjectProperties(id,generator()->maximumCMEnergy());
}
/**
* Jet properties
*/
ObjectProperties& jetProperties(const unsigned int id) {
map<unsigned int,ObjectProperties>::iterator h =
theJetProperties.find(id);
if ( h != theJetProperties.end() )
return h->second;
ostringstream ids; ids << "Jet" << id;
return
theJetProperties[id] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Exclusive jet properties
*/
ObjectProperties& exclusiveJetProperties(const unsigned int id) {
map<unsigned int,ObjectProperties>::iterator h =
theExclusiveJetProperties.find(id);
if ( h != theExclusiveJetProperties.end() )
return h->second;
ostringstream ids; ids << "ExclusiveJet" << id;
return
theExclusiveJetProperties[id] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet-inclusive properties
*/
ObjectProperties& jetInclusiveProperties() {
if ( !theJetInclusiveProperties.pt.bins().empty() )
return theJetInclusiveProperties;
return
theJetInclusiveProperties =
ObjectProperties("JetInclusive",generator()->maximumCMEnergy());
}
/**
* Jet-summed properties
*/
ObjectProperties& jetSummedProperties() {
if ( !theJetSummedProperties.pt.bins().empty() )
return theJetSummedProperties;
return
theJetSummedProperties =
ObjectProperties("JetSummed",generator()->maximumCMEnergy());
}
/**
* Jet-average properties
*/
ObjectProperties& jetAverageProperties() {
if ( !theJetAverageProperties.pt.bins().empty() )
return theJetAverageProperties;
return
theJetAverageProperties =
ObjectProperties("JetAverage",generator()->maximumCMEnergy());
}
/**
* Inclusive jet multiplicities
*/
Statistics::Histogram& nJetsInclusive() {
if ( !theNJetsInclusive.bins().empty() )
return theNJetsInclusive;
return
theNJetsInclusive =
Statistics::Histogram("NJetsInclusive",
Statistics::Histogram::regularBinEdges(-0.5,theJetRegions.size()+0.5,
theJetRegions.size()+1),
true,true);
}
/**
* Exclusive jet multiplicities
*/
Statistics::Histogram& nJetsExclusive() {
if ( !theNJetsExclusive.bins().empty() )
return theNJetsExclusive;
return
theNJetsExclusive =
Statistics::Histogram("NJetsExclusive",
Statistics::Histogram::regularBinEdges(-0.5,theJetRegions.size()+0.5,
theJetRegions.size()+1),
true,true);
}
/**
* Hard object pair properties
*/
PairProperties& hardPairProperties(const string& id, const string& jd) {
map<pair<string,string>,PairProperties>::iterator h =
theHardPairProperties.find(make_pair(id,jd));
if ( h != theHardPairProperties.end() )
return h->second;
return theHardPairProperties[make_pair(id,jd)] =
PairProperties(id+jd,generator()->maximumCMEnergy());
}
/**
* Jet pair properties
*/
PairProperties& jetPairProperties(const unsigned int id, const unsigned int jd) {
map<pair<unsigned int,unsigned int>,PairProperties>::iterator h =
theJetPairProperties.find(make_pair(id,jd));
if ( h != theJetPairProperties.end() )
return h->second;
ostringstream ids; ids << "Jet" << id << jd;
return theJetPairProperties[make_pair(id,jd)] =
PairProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet/hard pair properties
*/
PairProperties& jetHardPairProperties(const unsigned int id, const string& jd) {
map<pair<unsigned int,string>,PairProperties>::iterator h =
theJetHardPairProperties.find(make_pair(id,jd));
if ( h != theJetHardPairProperties.end() )
return h->second;
ostringstream ids; ids << "Jet" << id << jd;
return theJetHardPairProperties[make_pair(id,jd)] =
PairProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Trijet properties
*/
ObjectProperties& threeJetProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3) {
map<std::tuple<unsigned int,unsigned int,unsigned int>,ObjectProperties>::iterator it =
theThreeJetProperties.find(std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3));
if ( it != theThreeJetProperties.end() )
return it->second;
ostringstream ids;
ids << "Jet" << id1 << id2 << id3;
return theThreeJetProperties[std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3)] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Fourjet properties
*/
ObjectProperties& fourJetProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3, const unsigned int id4) {
map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties>::iterator it =
theFourJetProperties.find(std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>(id1,id2,id3,id4));
if ( it != theFourJetProperties.end() )
return it->second;
ostringstream ids;
ids << "Jet" << id1 << id2 << id3 << id4;
return theFourJetProperties[std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>(id1,id2,id3,id4)] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Perform any additional analysis required
*/
virtual void analyzeSpecial(long, double) {}
/**
* Append any additional histograms to the given histogram element
*/
virtual void finalize(XML::Element&) {}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
JetsPlusAnalysis & operator=(const JetsPlusAnalysis &) = delete;
};
}
#endif /* Herwig_JetsPlusAnalysis_H */
diff --git a/Analysis/LeptonsJetsAnalysis.cc b/Analysis/LeptonsJetsAnalysis.cc
--- a/Analysis/LeptonsJetsAnalysis.cc
+++ b/Analysis/LeptonsJetsAnalysis.cc
@@ -1,611 +1,609 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the LeptonsJetsAnalysis class.
//
#include "LeptonsJetsAnalysis.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/SubProcess.h"
#include "ThePEG/EventRecord/SubProcessGroup.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Handlers/EventHandler.h"
#include "ThePEG/Handlers/StandardEventHandler.h"
#include "Herwig/Sampling/GeneralSampler.h"
#include "Herwig/Utilities/XML/ElementIO.h"
using namespace Herwig;
LeptonsJetsAnalysis::LeptonsJetsAnalysis()
: theIsShowered(false), theApplyCuts(false) {}
-LeptonsJetsAnalysis::~LeptonsJetsAnalysis() {}
-
#ifndef LWH_AIAnalysisFactory_H
#ifndef LWH
#define LWH ThePEGLWH
#endif
#include "ThePEG/Analysis/LWH/AnalysisFactory.h"
#endif
struct SortPt {
inline bool operator()(const LorentzMomentum& a,
const LorentzMomentum& b) const {
return a.perp() > b.perp();
}
};
struct SortId {
inline bool operator()(const pair<PID,LorentzMomentum>& a,
const pair<PID,LorentzMomentum>& b) const {
// sort by abs(pid); if equal, first particle, then antiparticle
// this puts pairs forming bosons next to each other
long p1 = a.first;
long p2 = b.first;
if (abs(p1)==abs(p2)) {
return p1 > p2;
} else {
return abs(p1) < abs(p2);
}
}
};
void LeptonsJetsAnalysis::reconstructJets(const ParticleVector& parts) {
tcPDVector outType;
vector<LorentzMomentum> outMomenta;
for ( ParticleVector::const_iterator p = parts.begin();
p != parts.end(); ++p ) {
outType.push_back((**p).dataPtr());
outMomenta.push_back((**p).momentum());
}
jetFinder()->cluster(outType, outMomenta,
tcCutsPtr(), tcPDPtr(),tcPDPtr());
sort(outMomenta.begin(),outMomenta.end(),SortPt());
for ( vector<Ptr<JetRegion>::ptr>::iterator j =
theJetRegions.begin(); j != theJetRegions.end(); ++j )
(**j).reset();
for ( size_t k = 0; k < outMomenta.size(); ++k ) {
for ( vector<Ptr<JetRegion>::ptr>::const_iterator r = jetRegions().begin();
r != jetRegions().end(); ++r ) {
if ( (**r).matches(tCutsPtr(),k+1,outMomenta[k])) {
jetMomentum(k+1) = outMomenta[k];
break;
}
}
}
}
void LeptonsJetsAnalysis::reconstructEWParticles(ParticleVector& parts) {
vector< pair<PID,LorentzMomentum> > partall;
vector<LorentzMomentum> partl, partnu, parth;
LorentzMomentum ptmiss = LorentzMomentum(ZERO,ZERO,ZERO,ZERO);
ParticleVector::iterator p = parts.begin();
while (p != parts.end()) {
PID pid = (**p).id();
if ( ( static_cast<long>(pid) == ParticleID::eminus ) ||
( static_cast<long>(pid) == ParticleID::eplus ) ||
( static_cast<long>(pid) == ParticleID::muminus ) ||
( static_cast<long>(pid) == ParticleID::muplus ) ||
( static_cast<long>(pid) == ParticleID::tauminus ) ||
( static_cast<long>(pid) == ParticleID::tauplus ) ) {
partall.push_back(pair<PID,LorentzMomentum>(pid,(**p).momentum()));
partl.push_back((**p).momentum());
p = parts.erase(p);
} else
if ( ( static_cast<long>(pid) == ParticleID::nu_e ) ||
( static_cast<long>(pid) == ParticleID::nu_ebar ) ||
( static_cast<long>(pid) == ParticleID::nu_mu ) ||
( static_cast<long>(pid) == ParticleID::nu_mubar ) ||
( static_cast<long>(pid) == ParticleID::nu_tau ) ||
( static_cast<long>(pid) == ParticleID::nu_taubar ) ) {
partall.push_back(pair<PID,LorentzMomentum>(pid,(**p).momentum()));
partnu.push_back((**p).momentum());
ptmiss += (**p).momentum();
p = parts.erase(p);
} else
if ( static_cast<long>(pid) == ParticleID::h0 ) {
partall.push_back(pair<PID,LorentzMomentum>(pid,(**p).momentum()));
parth.push_back((**p).momentum());
p = parts.erase(p);
} else
p++;
}
sort(partall.begin(),partall.end(),SortId());
sort(partl.begin(),partl.end(),SortPt());
sort(partnu.begin(),partnu.end(),SortPt());
sort(parth.begin(),parth.end(),SortPt());
// make missing transverse momentum transverse and also add as last entry in EWID
ptmiss.setE(ptmiss.perp());
ptmiss.setZ(0*GeV);
partall.push_back(pair<PID,LorentzMomentum>(ParticleID::nu_e,ptmiss));
for ( size_t k = 0; k < partall.size(); ++k )
eWIDMomentum(k+1) = partall[k].second;
for ( size_t k = 0; k < partl.size(); ++k )
chargedLeptonMomentum(k+1) = partl[k];
for ( size_t k = 0; k < partnu.size(); ++k )
neutrinoMomentum(k+1) = partnu[k];
for ( size_t k = 0; k < parth.size(); ++k )
higgsMomentum(k+1) = parth[k];
pTmissMomentum() = ptmiss;
}
void LeptonsJetsAnalysis::analyze(ParticleVector& parts, long id, double weight) {
clear();
reconstructEWParticles(parts);
reconstructJets(parts);
if ( theApplyCuts ) {
// VBF cuts
if ( nJets()<2 ) return;
if ( (jetMomentum(1)+jetMomentum(2)).m() < 600*GeV ) return;
if ( abs(jetMomentum(1).rapidity()-jetMomentum(2).rapidity()) < 3.6 ) return;
// if ( jetMomentum(1).rapidity()*jetMomentum(2).rapidity() > 0 ) return;
for ( map<unsigned int,LorentzMomentum>::const_iterator h = theChargedLeptons.begin();
h != theChargedLeptons.end(); ++h ) {
if ( h->second.perp() < 20*GeV ) return;
if ( abs(h->second.rapidity()) > 2.5 ) return;
}
}
unsigned int njets = 0;
Energy jetSummedPerp = ZERO;
double jetSummedRapidity = 0.0;
double jetSummedPhi = 0.0;
Energy jetSummedM = ZERO;
nJetsInclusive().count(Statistics::EventContribution(njets,weight,0.0),id);
if ( njets == theJets.size() )
nJetsExclusive().count(Statistics::EventContribution(njets,weight,0.0),id);
for ( map<unsigned int,LorentzMomentum>::const_iterator h = theJets.begin();
h != theJets.end(); ++h ) {
njets += 1;
jetProperties(h->first).count(h->second,weight,id);
jetInclusiveProperties().count(h->second,weight,id);
nJetsInclusive().count(Statistics::EventContribution(njets,weight,0.0),id);
if ( njets == theJets.size() ) {
exclusiveJetProperties(h->first).count(h->second,weight,id);
nJetsExclusive().count(Statistics::EventContribution(njets,weight,0.0),id);
}
jetSummedPerp += h->second.perp();
jetSummedRapidity += h->second.rapidity();
jetSummedPhi += h->second.phi();
jetSummedM += h->second.m();
map<unsigned int,LorentzMomentum>::const_iterator g = h; ++g;
for ( ; g != theJets.end(); ++g ) {
jetPairProperties(h->first,g->first).count(h->second,g->second,weight,id);
map<unsigned int,LorentzMomentum>::const_iterator g1 = g; ++g1;
for ( ; g1 != theJets.end(); ++g1 ) {
threeJetProperties(h->first,g->first,g1->first).count(h->second,g->second,g1->second,weight,id);
map<unsigned int,LorentzMomentum>::const_iterator g2 = g1; ++g2;
for ( ; g2 != theJets.end(); ++g2 ) {
LorentzMomentum p1234 =
h->second + g->second + g1->second + g2->second;
fourJetProperties(h->first,g->first,g1->first,g2->first).count(p1234,weight,id);
}
}
for ( map<unsigned int,LorentzMomentum>::const_iterator g1 = theEWIDs.begin();
g1 != theEWIDs.end(); ++g1 )
jetPairEWIDTripleProperties(h->first,g->first,g1->first).count(h->second,g->second,g1->second,weight,id);
for ( map<unsigned int,LorentzMomentum>::const_iterator g1 = theChargedLeptons.begin();
g1 != theChargedLeptons.end(); ++g1 )
jetPairChargedLeptonTripleProperties(h->first,g->first,g1->first).count(h->second,g->second,g1->second,weight,id);
for ( map<unsigned int,LorentzMomentum>::const_iterator g1 = theNeutrinos.begin();
g1 != theNeutrinos.end(); ++g1 )
jetPairNeutrinoTripleProperties(h->first,g->first,g1->first).count(h->second,g->second,g1->second,weight,id);
jetPairPTmissTripleProperties(h->first,g->first).count(h->second,g->second,pTmissMomentum(),weight,id);
for ( map<unsigned int,LorentzMomentum>::const_iterator g1 = theHiggs.begin();
g1 != theHiggs.end(); ++g1 )
jetPairHiggsTripleProperties(h->first,g->first,g1->first).count(h->second,g->second,g1->second,weight,id);
}
for ( map<unsigned int,LorentzMomentum>::const_iterator g = theEWIDs.begin();
g != theEWIDs.end(); ++g )
jetEWIDPairProperties(h->first,g->first).count(h->second,g->second,weight,id);
for ( map<unsigned int,LorentzMomentum>::const_iterator g = theChargedLeptons.begin();
g != theChargedLeptons.end(); ++g )
jetChargedLeptonPairProperties(h->first,g->first).count(h->second,g->second,weight,id);
for ( map<unsigned int,LorentzMomentum>::const_iterator g = theNeutrinos.begin();
g != theNeutrinos.end(); ++g )
jetNeutrinoPairProperties(h->first,g->first).count(h->second,g->second,weight,id);
jetPTmissPairProperties(h->first).count(h->second,pTmissMomentum(),weight,id);
for ( map<unsigned int,LorentzMomentum>::const_iterator g = theHiggs.begin();
g != theHiggs.end(); ++g )
jetHiggsPairProperties(h->first,g->first).count(h->second,g->second,weight,id);
}
if ( njets > 0 )
jetSummedProperties().count(jetSummedPerp,jetSummedRapidity,
jetSummedPhi,jetSummedM,
weight,id);
if ( njets > 0 )
jetAverageProperties().count(jetSummedPerp/njets,jetSummedRapidity/njets,
jetSummedPhi/njets,jetSummedM/njets,
weight,id);
for ( map<unsigned int,LorentzMomentum>::const_iterator h = theEWIDs.begin();
h != theEWIDs.end(); ++h ) {
eWIDProperties(h->first).count(h->second,weight,id);
map<unsigned int,LorentzMomentum>::const_iterator g = h; ++g;
for ( ; g != theEWIDs.end(); ++g ) {
eWIDPairProperties(h->first,g->first).count(h->second,g->second,weight,id);
map<unsigned int,LorentzMomentum>::const_iterator g1 = g; ++g1;
for ( ; g1 != theEWIDs.end(); ++g1 ) {
threeEWIDProperties(h->first,g->first,g1->first).count(h->second,g->second,g1->second,weight,id);
map<unsigned int,LorentzMomentum>::const_iterator g2 = g1; ++g2;
for ( ; g2 != theEWIDs.end(); ++g2 ) {
LorentzMomentum p1234 =
h->second + g->second + g1->second + g2->second;
fourEWIDProperties(h->first,g->first,g1->first,g2->first).count(p1234,weight,id);
}
}
}
}
for ( map<unsigned int,LorentzMomentum>::const_iterator h = theChargedLeptons.begin();
h != theChargedLeptons.end(); ++h ) {
chargedLeptonProperties(h->first).count(h->second,weight,id);
map<unsigned int,LorentzMomentum>::const_iterator g = h; ++g;
for ( ; g != theChargedLeptons.end(); ++g ) {
chargedLeptonPairProperties(h->first,g->first).count(h->second,g->second,weight,id);
map<unsigned int,LorentzMomentum>::const_iterator g1 = g; ++g1;
for ( ; g1 != theChargedLeptons.end(); ++g1 ) {
threeChargedLeptonProperties(h->first,g->first,g1->first).count(h->second,g->second,g1->second,weight,id);
map<unsigned int,LorentzMomentum>::const_iterator g2 = g1; ++g2;
for ( ; g2 != theChargedLeptons.end(); ++g2 ) {
LorentzMomentum p1234 =
h->second + g->second + g1->second + g2->second;
fourChargedLeptonProperties(h->first,g->first,g1->first,g2->first).count(p1234,weight,id);
}
}
}
}
for ( map<unsigned int,LorentzMomentum>::const_iterator h = theNeutrinos.begin();
h != theNeutrinos.end(); ++h ) {
neutrinoProperties(h->first).count(h->second,weight,id);
}
pTmissProperties().count(pTmissMomentum(),weight,id);
for ( map<unsigned int,LorentzMomentum>::const_iterator h = theHiggs.begin();
h != theHiggs.end(); ++h ) {
higgsProperties(h->first).count(h->second,weight,id);
}
analyzeSpecial(id,weight);
}
void LeptonsJetsAnalysis::analyze(tEventPtr event, long ieve, int loop, int state) {
AnalysisHandler::analyze(event, ieve, loop, state);
Ptr<StandardEventHandler>::tptr seh =
dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(generator()->eventHandler());
Ptr<GeneralSampler>::tptr sampler =
dynamic_ptr_cast<Ptr<GeneralSampler>::tptr>(seh->sampler());
double norm = sampler->maxXSec()/picobarn;
if ( !theIsShowered ) {
tSubProPtr sub = event->primarySubProcess();
Ptr<SubProcessGroup>::tptr grp =
dynamic_ptr_cast<Ptr<SubProcessGroup>::tptr>(sub);
ParticleVector hfs = sub->outgoing();
analyze(hfs,ieve,norm*event->weight()*sub->groupWeight());
if ( grp ) {
for ( SubProcessVector::const_iterator s = grp->dependent().begin();
s != grp->dependent().end(); ++s ) {
ParticleVector fs = (**s).outgoing();
analyze(fs,ieve,norm*event->weight()*(**s).groupWeight());
}
}
} else {
ParticleVector fs;
event->getFinalState(fs);
analyze(fs,ieve,norm*event->weight());
}
}
void LeptonsJetsAnalysis::dofinish() {
AnalysisHandler::dofinish();
Ptr<StandardEventHandler>::tptr seh =
dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(generator()->eventHandler());
Ptr<GeneralSampler>::tptr sampler =
dynamic_ptr_cast<Ptr<GeneralSampler>::tptr>(seh->sampler());
unsigned long attemptedPoints = sampler->attempts();
double sumOfWeights = sampler->sumWeights();
double sumOfSquaredWeights = sampler->sumWeights2();
CrossSection maxXSection = sampler->maxXSec();
XML::Element elem(XML::ElementTypes::Element,"Run");
elem.appendAttribute("name",generator()->runName());
elem.appendAttribute("attemptedPoints",attemptedPoints);
elem.appendAttribute("sumOfWeights",sumOfWeights*maxXSection/picobarn);
elem.appendAttribute("sumOfSquaredWeights",sumOfSquaredWeights*sqr(maxXSection/picobarn));
XML::Element xhistos(XML::ElementTypes::Element,"Histograms");
for ( map<unsigned int,ObjectProperties>::iterator h = theJetProperties.begin();
h != theJetProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<unsigned int,ObjectProperties>::iterator h = theExclusiveJetProperties.begin();
h != theExclusiveJetProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
if ( !theJetInclusiveProperties.pt.bins().empty() ) {
theJetInclusiveProperties.finalize(xhistos);
}
if ( !theJetSummedProperties.pt.bins().empty() ) {
theJetSummedProperties.finalize(xhistos);
}
if ( !theJetAverageProperties.pt.bins().empty() ) {
theJetAverageProperties.finalize(xhistos);
}
if ( !theNJetsInclusive.bins().empty() ) {
theNJetsInclusive.finalize();
xhistos.append(theNJetsInclusive.toXML());
}
if ( !theNJetsExclusive.bins().empty() ) {
theNJetsExclusive.finalize();
xhistos.append(theNJetsExclusive.toXML());
}
for ( map<unsigned int,ObjectProperties>::iterator h = theEWIDProperties.begin();
h != theEWIDProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<unsigned int,ObjectProperties>::iterator h = theChargedLeptonProperties.begin();
h != theChargedLeptonProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<unsigned int,ObjectProperties>::iterator h = theNeutrinoProperties.begin();
h != theNeutrinoProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
thePTmissProperties.finalize(xhistos);
for ( map<unsigned int,ObjectProperties>::iterator h = theHiggsProperties.begin();
h != theHiggsProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<pair<unsigned int,unsigned int>,PairProperties>::iterator h = theJetPairProperties.begin();
h != theJetPairProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<pair<unsigned int,unsigned int>,PairProperties>::iterator h = theJetEWIDPairProperties.begin();
h != theJetEWIDPairProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<pair<unsigned int,unsigned int>,PairProperties>::iterator h = theJetChargedLeptonPairProperties.begin();
h != theJetChargedLeptonPairProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<pair<unsigned int,unsigned int>,PairProperties>::iterator h = theJetNeutrinoPairProperties.begin();
h != theJetNeutrinoPairProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<unsigned int,PairProperties>::iterator h = theJetPTmissPairProperties.begin();
h != theJetPTmissPairProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<pair<unsigned int,unsigned int>,PairProperties>::iterator h = theJetHiggsPairProperties.begin();
h != theJetHiggsPairProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<pair<unsigned int,unsigned int>,PairProperties>::iterator h = theEWIDPairProperties.begin();
h != theEWIDPairProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<pair<unsigned int,unsigned int>,PairProperties>::iterator h = theChargedLeptonPairProperties.begin();
h != theChargedLeptonPairProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator h =
theThreeJetProperties.begin(); h != theThreeJetProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator h =
theJetPairEWIDTripleProperties.begin(); h != theJetPairEWIDTripleProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator h =
theJetPairChargedLeptonTripleProperties.begin(); h != theJetPairChargedLeptonTripleProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator h =
theJetPairNeutrinoTripleProperties.begin(); h != theJetPairNeutrinoTripleProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<pair<unsigned int,unsigned int>,TripleProperties>::iterator h =
theJetPairPTmissTripleProperties.begin(); h != theJetPairPTmissTripleProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator h =
theJetPairHiggsTripleProperties.begin(); h != theJetPairHiggsTripleProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator h =
theThreeEWIDProperties.begin(); h != theThreeEWIDProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator h =
theThreeChargedLeptonProperties.begin(); h != theThreeChargedLeptonProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties>::iterator h =
theFourJetProperties.begin(); h != theFourJetProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties>::iterator h =
theFourEWIDProperties.begin(); h != theFourEWIDProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
for ( map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties>::iterator h =
theFourChargedLeptonProperties.begin(); h != theFourChargedLeptonProperties.end(); ++h ) {
h->second.finalize(xhistos);
}
finalize(xhistos);
elem.append(xhistos);
string fname = generator()->filename() + string("-") + name() + string(".xml");
ofstream runXML(fname.c_str());
runXML << setprecision(16);
XML::ElementIO::put(elem,runXML);
}
IBPtr LeptonsJetsAnalysis::clone() const {
return new_ptr(*this);
}
IBPtr LeptonsJetsAnalysis::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void LeptonsJetsAnalysis::persistentOutput(PersistentOStream & os) const {
os << theIsShowered << theApplyCuts << theJetFinder << theJetRegions;
}
void LeptonsJetsAnalysis::persistentInput(PersistentIStream & is, int) {
is >> theIsShowered >> theApplyCuts >> theJetFinder >> theJetRegions;
}
// *** 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<LeptonsJetsAnalysis,AnalysisHandler>
describeHerwigLeptonsJetsAnalysis("Herwig::LeptonsJetsAnalysis", "JetCuts.so HwJetsAnalysis.so");
void LeptonsJetsAnalysis::Init() {
static ClassDocumentation<LeptonsJetsAnalysis> documentation
("General-purpose analysis for processes with jets and leptons");
static Reference<LeptonsJetsAnalysis,JetFinder> interfaceJetFinder
("JetFinder",
"",
&LeptonsJetsAnalysis::theJetFinder, false, false, true, false, false);
static RefVector<LeptonsJetsAnalysis,JetRegion> interfaceJetRegions
("JetRegions",
"",
&LeptonsJetsAnalysis::theJetRegions, -1, false, false, true, false, false);
static Switch<LeptonsJetsAnalysis,bool> interfaceIsShowered
("IsShowered",
"",
&LeptonsJetsAnalysis::theIsShowered, false, false, false);
static SwitchOption interfaceIsShoweredYes
(interfaceIsShowered,
"Yes",
"",
true);
static SwitchOption interfaceIsShoweredNo
(interfaceIsShowered,
"No",
"",
false);
static Switch<LeptonsJetsAnalysis,bool> interfaceApplyCuts
("ApplyCuts",
"",
&LeptonsJetsAnalysis::theApplyCuts, false, false, false);
static SwitchOption interfaceApplyCutsYes
(interfaceApplyCuts,
"Yes",
"",
true);
static SwitchOption interfaceApplyCutsNo
(interfaceApplyCuts,
"No",
"",
false);
}
diff --git a/Analysis/LeptonsJetsAnalysis.h b/Analysis/LeptonsJetsAnalysis.h
--- a/Analysis/LeptonsJetsAnalysis.h
+++ b/Analysis/LeptonsJetsAnalysis.h
@@ -1,1137 +1,1129 @@
// -*- C++ -*-
#ifndef Herwig_LeptonsJetsAnalysis_H
#define Herwig_LeptonsJetsAnalysis_H
//
// This is the declaration of the LeptonsJetsAnalysis class.
//
#include "ThePEG/Handlers/AnalysisHandler.h"
#include "ThePEG/Cuts/JetFinder.h"
#include "ThePEG/Cuts/JetRegion.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Utilities/Statistics/Histogram.h"
namespace Herwig {
using namespace ThePEG;
/**
* Here is the documentation of the LeptonsJetsAnalysis class.
*
* @see \ref LeptonsJetsAnalysisInterfaces "The interfaces"
* defined for LeptonsJetsAnalysis.
*/
class LeptonsJetsAnalysis: public AnalysisHandler {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
LeptonsJetsAnalysis();
- /**
- * The destructor.
- */
- virtual ~LeptonsJetsAnalysis();
- //@}
-
public:
/** @name Virtual functions required by the AnalysisHandler class. */
//@{
/**
* Analyze a given Event. Note that a fully generated event
* may be presented several times, if it has been manipulated in
* between. The default version of this function will call transform
* to make a lorentz transformation of the whole event, then extract
* all final state particles and call analyze(tPVector) of this
* analysis object and those of all associated analysis objects. The
* default version will not, however, do anything on events which
* have not been fully generated, or have been manipulated in any
* way.
* @param event pointer to the Event to be analyzed.
* @param ieve the event number.
* @param loop the number of times this event has been presented.
* If negative the event is now fully generated.
* @param state a number different from zero if the event has been
* manipulated in some way since it was last presented.
*/
virtual void analyze(tEventPtr event, long ieve, int loop, int state);
//@}
protected:
/**
* Analyze one subprocess, given the event number it belongs to
*/
void analyze(ParticleVector&, long, double);
/**
* Clear the electroweak objects and jets for the next event
*/
void clear() {
theJets.clear();
theEWIDs.clear();
theChargedLeptons.clear();
theNeutrinos.clear();
theHiggs.clear();
}
/**
* Reconstruct the jets and fill the respective momenta.
*/
virtual void reconstructJets(const ParticleVector&);
/**
* The jet finder to use
*/
Ptr<JetFinder>::tptr jetFinder() const {
return theJetFinder;
}
/**
* The jet regions to match.
*/
const vector<Ptr<JetRegion>::ptr>& jetRegions() const { return theJetRegions; }
/**
* Return the number of matched jets
*/
unsigned int nJets() const { return theJets.size(); }
/**
* Set the momentum of the indicated jet.
*/
LorentzMomentum& jetMomentum(const unsigned int id) {
return theJets[id];
}
/**
* Reconstruct all the variables for EW particles and fill the respective momenta.
*/
virtual void reconstructEWParticles(ParticleVector&);
/**
* Set the momentum of the indicated electroweak particle.
*/
LorentzMomentum& eWIDMomentum(const unsigned int id) {
return theEWIDs[id];
}
/**
* Set the momentum of the indicated charged lepton.
*/
LorentzMomentum& chargedLeptonMomentum(const unsigned int id) {
return theChargedLeptons[id];
}
/**
* Set the momentum of the indicated neutrino.
*/
LorentzMomentum& neutrinoMomentum(const unsigned int id) {
return theNeutrinos[id];
}
/**
* Set the missing pT momentum.
*/
LorentzMomentum& pTmissMomentum() {
return thePTmiss;
}
/**
* Set the momentum of the indicated Higgs.
*/
LorentzMomentum& higgsMomentum(const unsigned int id) {
return theHiggs[id];
}
protected:
/**
* Finalize this object. Called in the run phase just after a
* run has ended. Used eg. to write out statistics.
*/
virtual void dofinish();
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:
/**
* Collection of object histograms; ranges are adjusted to the
* maximum, so range constraints and rebinning can be applied later.
*/
struct ObjectProperties {
/**
* Transverse momentum
*/
Statistics::Histogram pt;
Statistics::Histogram ptlow;
Statistics::Histogram pt_logx;
/**
* Rapidity
*/
Statistics::Histogram y;
/**
* Azimuth
*/
Statistics::Histogram phi;
/**
* Mass
*/
Statistics::Histogram mass;
Statistics::Histogram masslow;
/**
* Default constructor
*/
ObjectProperties() {}
/**
* Construct given Ecm
*/
ObjectProperties(const string& name, Energy)
: pt(name + "Pt",Statistics::Histogram::regularBinEdges(0,1000,200),true,false),
ptlow(name + "Ptlow",Statistics::Histogram::regularBinEdges(0,200,100),true,false),
pt_logx(name + "PtLogX",Statistics::Histogram::logBinEdges(0.1,1000,100),true,false),
y(name + "Y",Statistics::Histogram::regularBinEdges(-6,6,120),false,false),
phi(name + "Phi",Statistics::Histogram::regularBinEdges(-Constants::pi,Constants::pi,62),
make_pair(-Constants::pi,Constants::pi)),
mass(name + "Mass",Statistics::Histogram::regularBinEdges(0,5000,500),true,false),
masslow(name + "Masslow",Statistics::Histogram::regularBinEdges(0,250,100),true,false) {}
/**
* Count given momentum, weight and id
*/
void count(const LorentzMomentum& p, double weight, unsigned int id) {
pt.count(Statistics::EventContribution(p.perp()/GeV,weight,5.),id);
ptlow.count(Statistics::EventContribution(p.perp()/GeV,weight,2.),id);
pt_logx.count(Statistics::EventContribution(p.perp()/GeV,weight,1.),id);
y.count(Statistics::EventContribution(p.rapidity(),weight,0.1),id);
phi.count(Statistics::EventContribution(p.phi(),weight,0.1),id);
mass.count(Statistics::EventContribution(p.m()/GeV,weight,10.),id);
masslow.count(Statistics::EventContribution(p.m()/GeV,weight,2.5),id);
}
/**
* Count given momentum components, weight and id
*/
void count(Energy perp, double rapidity,
double xphi, Energy m,
double weight, unsigned int id) {
pt.count(Statistics::EventContribution(perp/GeV,weight,5.),id);
ptlow.count(Statistics::EventContribution(perp/GeV,weight,1.),id);
pt_logx.count(Statistics::EventContribution(perp/GeV,weight,1.),id);
y.count(Statistics::EventContribution(rapidity,weight,0.1),id);
phi.count(Statistics::EventContribution(xphi,weight,0.1),id);
mass.count(Statistics::EventContribution(m/GeV,weight,5.),id);
masslow.count(Statistics::EventContribution(m/GeV,weight,1.25),id);
}
/**
* Convert to XML
*/
void finalize(XML::Element& elem) {
pt.finalize(); elem.append(pt.toXML());
ptlow.finalize(); elem.append(ptlow.toXML());
pt_logx.finalize(); elem.append(pt_logx.toXML());
y.finalize(); elem.append(y.toXML());
phi.finalize(); elem.append(phi.toXML());
mass.finalize(); elem.append(mass.toXML());
masslow.finalize(); elem.append(masslow.toXML());
}
};
/**
* Collection of pair histograms; ranges are adjusted to the
* maximum, so range constraints and rebinning can be applied later.
*/
struct PairProperties
: public ObjectProperties {
/**
* Calculate deltaPhi
*/
static double dPhi(const LorentzMomentum& a,
const LorentzMomentum& b){
double phi1 = a.phi();
double phi2 = b.phi();
double diff=phi1-phi2;
if(diff<-Constants::pi){
diff+=(2.0*Constants::pi);
}
else if (diff>Constants::pi){
diff-=(2.0*Constants::pi);
}
return diff;
}
/**
* Calculate deltaY
*/
static double dY(const LorentzMomentum& a,
const LorentzMomentum& b){
return abs(a.rapidity()-b.rapidity());
}
/**
* Calculate deltaR
*/
static double dR(const LorentzMomentum& a,
const LorentzMomentum& b){
return sqrt(sqr(dPhi(a,b))+sqr(dY(a,b)));
}
/**
* Calculate ydoty
*/
static double yy(const LorentzMomentum& a,
const LorentzMomentum& b){
double ya = a.rapidity();
double yb = b.rapidity();
double yres = sqrt(abs(ya*yb));
return ya*yb < 0. ? -yres : yres;
}
/**
* Delta y
*/
Statistics::Histogram deltaY;
/**
* Delta phi
*/
Statistics::Histogram deltaPhi;
/**
* Delta phi
*/
Statistics::Histogram deltaR;
/**
* Product of the rapidities
*/
Statistics::Histogram yDotY;
/**
* Default constructor
*/
PairProperties()
: ObjectProperties() {}
/**
* Construct given Ecm
*/
PairProperties(const string& name, Energy ecm)
: ObjectProperties(name,ecm),
deltaY(name + "DeltaY",Statistics::Histogram::regularBinEdges(0,6,60),true,false),
deltaPhi(name + "DeltaPhi",Statistics::Histogram::regularBinEdges(-Constants::pi,Constants::pi,32),
make_pair(-Constants::pi,Constants::pi)),
deltaR(name + "DeltaR",Statistics::Histogram::regularBinEdges(0,10,100),true,false),
yDotY(name + "YDotY",Statistics::Histogram::regularBinEdges(-6,6,120),false,false) {}
/**
* Count given momentum, weight and id
*/
void count(const LorentzMomentum& p, const LorentzMomentum& q, double weight, unsigned int id) {
ObjectProperties::count(p+q,weight,id);
deltaY.count(Statistics::EventContribution(dY(p,q),weight,0.1),id);
deltaPhi.count(Statistics::EventContribution(dPhi(p,q),weight,0.1),id);
deltaR.count(Statistics::EventContribution(dR(p,q),weight,0.1),id);
yDotY.count(Statistics::EventContribution(yy(p,q),weight,0.1),id);
}
/**
* Convert to XML
*/
void finalize(XML::Element& elem) {
ObjectProperties::finalize(elem);
deltaY.finalize(); elem.append(deltaY.toXML());
deltaPhi.finalize(); elem.append(deltaPhi.toXML());
deltaR.finalize(); elem.append(deltaR.toXML());
yDotY.finalize(); elem.append(yDotY.toXML());
}
};
/**
* Collection of triple histograms; ranges are adjusted to the
* maximum, so range constraints and rebinning can be applied later.
*/
struct TripleProperties
: public ObjectProperties {
/**
* Calculate deltaY^*
*/
static double dYstar(const LorentzMomentum& a,
const LorentzMomentum& b,
const LorentzMomentum& c){
return c.rapidity()-(a.rapidity()+b.rapidity())/2.;
}
/**
* Calculate deltaZ^* -- normalized deltaY^*
*/
static double dZstar(const LorentzMomentum& a,
const LorentzMomentum& b,
const LorentzMomentum& c){
return dYstar(a,b,c)*2./abs(a.rapidity()-b.rapidity());
}
/**
* Delta y^*
*/
Statistics::Histogram deltaYstar;
/**
* Delta z^*
*/
Statistics::Histogram deltaZstar;
/**
* Default constructor
*/
TripleProperties()
: ObjectProperties() {}
/**
* Construct given Ecm
*/
TripleProperties(const string& name, Energy ecm)
: ObjectProperties(name,ecm),
deltaYstar(name + "DeltaYstar",Statistics::Histogram::regularBinEdges(-6,6,120),true,false),
deltaZstar(name + "DeltaZstar",Statistics::Histogram::regularBinEdges(-3,3,120),true,false) {}
/**
* Count given momentum, weight and id
*/
void count(const LorentzMomentum& p, const LorentzMomentum& q, const LorentzMomentum& r,
double weight, unsigned int id) {
ObjectProperties::count(p+q+r,weight,id);
deltaYstar.count(Statistics::EventContribution(dYstar(p,q,r),weight,0.1),id);
deltaZstar.count(Statistics::EventContribution(dZstar(p,q,r),weight,0.05),id);
}
/**
* Convert to XML
*/
void finalize(XML::Element& elem) {
ObjectProperties::finalize(elem);
deltaYstar.finalize(); elem.append(deltaYstar.toXML());
deltaZstar.finalize(); elem.append(deltaZstar.toXML());
}
};
private:
/**
* Switch between fixed order and showered
*/
bool theIsShowered;
/**
* Switch whether to apply extra analysis cuts
*/
bool theApplyCuts;
/**
* The jet finder to use
*/
Ptr<JetFinder>::ptr theJetFinder;
/**
* The jet regions to match.
*/
vector<Ptr<JetRegion>::ptr> theJetRegions;
/**
* The reconstructed jets
*/
map<unsigned int,LorentzMomentum> theJets;
/**
* The reconstructed electroweak particles
*/
map<unsigned int,LorentzMomentum> theEWIDs;
/**
* The reconstructed charged leptons
*/
map<unsigned int,LorentzMomentum> theChargedLeptons;
/**
* The reconstructed neutrinos
*/
map<unsigned int,LorentzMomentum> theNeutrinos;
/**
* The reconstructed missing pT
*/
LorentzMomentum thePTmiss;
/**
* The reconstructed Higgs
*/
map<unsigned int,LorentzMomentum> theHiggs;
/**
* Jet properties
*/
map<unsigned int,ObjectProperties> theJetProperties;
/**
* Exclusive jet properties
*/
map<unsigned int,ObjectProperties> theExclusiveJetProperties;
/**
* Jet-inclusive properties
*/
ObjectProperties theJetInclusiveProperties;
/**
* Jet-summed properties
*/
ObjectProperties theJetSummedProperties;
/**
* Jet-average properties
*/
ObjectProperties theJetAverageProperties;
/**
* Inclusive jet multiplicities
*/
Statistics::Histogram theNJetsInclusive;
/**
* Exclusive jet multiplicities
*/
Statistics::Histogram theNJetsExclusive;
/**
* Electroweak properties
*/
map<unsigned int,ObjectProperties> theEWIDProperties;
/**
* Charged lepton properties
*/
map<unsigned int,ObjectProperties> theChargedLeptonProperties;
/**
* Neutrino properties
*/
map<unsigned int,ObjectProperties> theNeutrinoProperties;
/**
* missing pT properties
*/
ObjectProperties thePTmissProperties;
/**
* Higgs properties
*/
map<unsigned int,ObjectProperties> theHiggsProperties;
/**
* Jet pair properties
*/
map<pair<unsigned int,unsigned int>,PairProperties> theJetPairProperties;
/**
* Jet/electroweak pair properties
*/
map<pair<unsigned int,unsigned int>,PairProperties> theJetEWIDPairProperties;
/**
* Jet/charged lepton pair properties
*/
map<pair<unsigned int,unsigned int>,PairProperties> theJetChargedLeptonPairProperties;
/**
* Jet/neutrino pair properties
*/
map<pair<unsigned int,unsigned int>,PairProperties> theJetNeutrinoPairProperties;
/**
* Jet/missing pT pair properties
*/
map<unsigned int,PairProperties> theJetPTmissPairProperties;
/**
* Jet/Higgs pair properties
*/
map<pair<unsigned int,unsigned int>,PairProperties> theJetHiggsPairProperties;
/**
* Electroweak pair properties
*/
map<pair<unsigned int,unsigned int>,PairProperties> theEWIDPairProperties;
/**
* Charged lepton pair properties
*/
map<pair<unsigned int,unsigned int>,PairProperties> theChargedLeptonPairProperties;
/**
* Trijet properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties> theThreeJetProperties;
/**
* Jet-pair/electroweak triple properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties> theJetPairEWIDTripleProperties;
/**
* Jet-pair/charged lepton triple properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties> theJetPairChargedLeptonTripleProperties;
/**
* Jet-pair/neutrino triple properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties> theJetPairNeutrinoTripleProperties;
/**
* Jet-pair/missing pT triple properties
*/
map<pair<unsigned int,unsigned int>,TripleProperties> theJetPairPTmissTripleProperties;
/**
* Jet-pair/Higgs triple properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties> theJetPairHiggsTripleProperties;
/**
* Triple electroweak properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties> theThreeEWIDProperties;
/**
* Triple charged lepton properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties> theThreeChargedLeptonProperties;
/**
* Fourjet properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties> theFourJetProperties;
/**
* Four electroweak properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties> theFourEWIDProperties;
/**
* Four charged lepton properties
*/
map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties> theFourChargedLeptonProperties;
protected:
/**
* Jet properties
*/
ObjectProperties& jetProperties(const unsigned int id) {
map<unsigned int,ObjectProperties>::iterator h =
theJetProperties.find(id);
if ( h != theJetProperties.end() )
return h->second;
ostringstream ids; ids << "Jet" << id;
return
theJetProperties[id] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Exclusive jet properties
*/
ObjectProperties& exclusiveJetProperties(const unsigned int id) {
map<unsigned int,ObjectProperties>::iterator h =
theExclusiveJetProperties.find(id);
if ( h != theExclusiveJetProperties.end() )
return h->second;
ostringstream ids; ids << "ExclusiveJet" << id;
return
theExclusiveJetProperties[id] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet-inclusive properties
*/
ObjectProperties& jetInclusiveProperties() {
if ( !theJetInclusiveProperties.pt.bins().empty() )
return theJetInclusiveProperties;
return
theJetInclusiveProperties =
ObjectProperties("JetInclusive",generator()->maximumCMEnergy());
}
/**
* Jet-summed properties
*/
ObjectProperties& jetSummedProperties() {
if ( !theJetSummedProperties.pt.bins().empty() )
return theJetSummedProperties;
return
theJetSummedProperties =
ObjectProperties("JetSummed",generator()->maximumCMEnergy());
}
/**
* Jet-average properties
*/
ObjectProperties& jetAverageProperties() {
if ( !theJetAverageProperties.pt.bins().empty() )
return theJetAverageProperties;
return
theJetAverageProperties =
ObjectProperties("JetAverage",generator()->maximumCMEnergy());
}
/**
* Inclusive jet multiplicities
*/
Statistics::Histogram& nJetsInclusive() {
if ( !theNJetsInclusive.bins().empty() )
return theNJetsInclusive;
return
theNJetsInclusive =
Statistics::Histogram("NJetsInclusive",
Statistics::Histogram::regularBinEdges(-0.5,theJetRegions.size()+0.5,
theJetRegions.size()+1),
true,true);
}
/**
* Exclusive jet multiplicities
*/
Statistics::Histogram& nJetsExclusive() {
if ( !theNJetsExclusive.bins().empty() )
return theNJetsExclusive;
return
theNJetsExclusive =
Statistics::Histogram("NJetsExclusive",
Statistics::Histogram::regularBinEdges(-0.5,theJetRegions.size()+0.5,
theJetRegions.size()+1),
true,true);
}
/**
* Lepton properties -- all sorted by ID
*/
ObjectProperties& eWIDProperties(const unsigned int id) {
map<unsigned int,ObjectProperties>::iterator h =
theEWIDProperties.find(id);
if ( h != theEWIDProperties.end() )
return h->second;
ostringstream ids; ids << "EWID" << id;
return
theEWIDProperties[id] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Charged lepton properties
*/
ObjectProperties& chargedLeptonProperties(const unsigned int id) {
map<unsigned int,ObjectProperties>::iterator h =
theChargedLeptonProperties.find(id);
if ( h != theChargedLeptonProperties.end() )
return h->second;
ostringstream ids; ids << "ChargedLepton" << id;
return
theChargedLeptonProperties[id] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Neutrino properties
*/
ObjectProperties& neutrinoProperties(const unsigned int id) {
map<unsigned int,ObjectProperties>::iterator h =
theNeutrinoProperties.find(id);
if ( h != theNeutrinoProperties.end() )
return h->second;
ostringstream ids; ids << "Neutrino" << id;
return
theNeutrinoProperties[id] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Missing pT properties
*/
ObjectProperties& pTmissProperties() {
if ( !thePTmissProperties.pt.bins().empty() )
return thePTmissProperties;
return
thePTmissProperties =
ObjectProperties("PTmiss",generator()->maximumCMEnergy());
}
/**
* Higgs properties
*/
ObjectProperties& higgsProperties(const unsigned int id) {
map<unsigned int,ObjectProperties>::iterator h =
theHiggsProperties.find(id);
if ( h != theHiggsProperties.end() )
return h->second;
ostringstream ids; ids << "Higgs" << id;
return
theHiggsProperties[id] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet pair properties
*/
PairProperties& jetPairProperties(const unsigned int id, const unsigned int jd) {
map<pair<unsigned int,unsigned int>,PairProperties>::iterator h =
theJetPairProperties.find(make_pair(id,jd));
if ( h != theJetPairProperties.end() )
return h->second;
ostringstream ids; ids << "Jet" << id << jd;
return theJetPairProperties[make_pair(id,jd)] =
PairProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet/lepton(all sorted by ID) pair properties
*/
PairProperties& jetEWIDPairProperties(const unsigned int id, const unsigned int jd) {
map<pair<unsigned int,unsigned int>,PairProperties>::iterator h =
theJetEWIDPairProperties.find(make_pair(id,jd));
if ( h != theJetEWIDPairProperties.end() )
return h->second;
ostringstream ids; ids << "Jet" << id << "EWID" << jd;
return theJetEWIDPairProperties[make_pair(id,jd)] =
PairProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet/charged lepton pair properties
*/
PairProperties& jetChargedLeptonPairProperties(const unsigned int id, const unsigned int jd) {
map<pair<unsigned int,unsigned int>,PairProperties>::iterator h =
theJetChargedLeptonPairProperties.find(make_pair(id,jd));
if ( h != theJetChargedLeptonPairProperties.end() )
return h->second;
ostringstream ids; ids << "Jet" << id << "ChargedLepton" << jd;
return theJetChargedLeptonPairProperties[make_pair(id,jd)] =
PairProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet/neutrino pair properties
*/
PairProperties& jetNeutrinoPairProperties(const unsigned int id, const unsigned int jd) {
map<pair<unsigned int,unsigned int>,PairProperties>::iterator h =
theJetNeutrinoPairProperties.find(make_pair(id,jd));
if ( h != theJetNeutrinoPairProperties.end() )
return h->second;
ostringstream ids; ids << "Jet" << id << "Neutrino" << jd;
return theJetNeutrinoPairProperties[make_pair(id,jd)] =
PairProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet/missing pT pair properties
*/
PairProperties& jetPTmissPairProperties(const unsigned int id) {
map<unsigned int,PairProperties>::iterator h =
theJetPTmissPairProperties.find(id);
if ( h != theJetPTmissPairProperties.end() )
return h->second;
ostringstream ids; ids << "Jet" << id << "PTmiss";
return theJetPTmissPairProperties[id] =
PairProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet/Higgs pair properties
*/
PairProperties& jetHiggsPairProperties(const unsigned int id, const unsigned int jd) {
map<pair<unsigned int,unsigned int>,PairProperties>::iterator h =
theJetHiggsPairProperties.find(make_pair(id,jd));
if ( h != theJetHiggsPairProperties.end() )
return h->second;
ostringstream ids; ids << "Jet" << id << "Higgs" << jd;
return theJetHiggsPairProperties[make_pair(id,jd)] =
PairProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Electroweak pair properties
*/
PairProperties& eWIDPairProperties(const unsigned int id, const unsigned int jd) {
map<pair<unsigned int,unsigned int>,PairProperties>::iterator h =
theEWIDPairProperties.find(make_pair(id,jd));
if ( h != theEWIDPairProperties.end() )
return h->second;
ostringstream ids; ids << "EWID" << id << jd;
return theEWIDPairProperties[make_pair(id,jd)] =
PairProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Charged lepton pair properties
*/
PairProperties& chargedLeptonPairProperties(const unsigned int id, const unsigned int jd) {
map<pair<unsigned int,unsigned int>,PairProperties>::iterator h =
theChargedLeptonPairProperties.find(make_pair(id,jd));
if ( h != theChargedLeptonPairProperties.end() )
return h->second;
ostringstream ids; ids << "ChargedLepton" << id << jd;
return theChargedLeptonPairProperties[make_pair(id,jd)] =
PairProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Trijet properties
*/
TripleProperties& threeJetProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3) {
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator it =
theThreeJetProperties.find(std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3));
if ( it != theThreeJetProperties.end() )
return it->second;
ostringstream ids;
ids << "Jet" << id1 << id2 << id3;
return theThreeJetProperties[std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3)] =
TripleProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet-pair/electroweak triple properties
*/
TripleProperties& jetPairEWIDTripleProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3) {
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator it =
theJetPairEWIDTripleProperties.find(std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3));
if ( it != theJetPairEWIDTripleProperties.end() )
return it->second;
ostringstream ids;
ids << "Jet" << id1 << id2 << "EWID" << id3;
return theJetPairEWIDTripleProperties[std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3)] =
TripleProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet-pair/charged lepton triple properties
*/
TripleProperties& jetPairChargedLeptonTripleProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3) {
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator it =
theJetPairChargedLeptonTripleProperties.find(std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3));
if ( it != theJetPairChargedLeptonTripleProperties.end() )
return it->second;
ostringstream ids;
ids << "Jet" << id1 << id2 << "ChargedLepton" << id3;
return theJetPairChargedLeptonTripleProperties[std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3)] =
TripleProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet-pair/neutrino triple properties
*/
TripleProperties& jetPairNeutrinoTripleProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3) {
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator it =
theJetPairNeutrinoTripleProperties.find(std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3));
if ( it != theJetPairNeutrinoTripleProperties.end() )
return it->second;
ostringstream ids;
ids << "Jet" << id1 << id2 << "Neutrino" << id3;
return theJetPairNeutrinoTripleProperties[std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3)] =
TripleProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet-pair/missing pT triple properties
*/
TripleProperties& jetPairPTmissTripleProperties(const unsigned int id1, const unsigned int id2) {
map<pair<unsigned int,unsigned int>,TripleProperties>::iterator it =
theJetPairPTmissTripleProperties.find(pair<unsigned int,unsigned int>(id1,id2));
if ( it != theJetPairPTmissTripleProperties.end() )
return it->second;
ostringstream ids;
ids << "Jet" << id1 << id2 << "PTmiss";
return theJetPairPTmissTripleProperties[pair<unsigned int,unsigned int>(id1,id2)] =
TripleProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Jet-pair/Higgs triple properties
*/
TripleProperties& jetPairHiggsTripleProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3) {
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator it =
theJetPairHiggsTripleProperties.find(std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3));
if ( it != theJetPairHiggsTripleProperties.end() )
return it->second;
ostringstream ids;
ids << "Jet" << id1 << id2 << "Higgs" << id3;
return theJetPairHiggsTripleProperties[std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3)] =
TripleProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Triple electroweak properties -- all sorted by ID
*/
TripleProperties& threeEWIDProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3) {
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator it =
theThreeEWIDProperties.find(std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3));
if ( it != theThreeEWIDProperties.end() )
return it->second;
ostringstream ids;
ids << "EWID" << id1 << id2 << id3;
return theThreeEWIDProperties[std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3)] =
TripleProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Triple charged lepton properties
*/
TripleProperties& threeChargedLeptonProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3) {
map<std::tuple<unsigned int,unsigned int,unsigned int>,TripleProperties>::iterator it =
theThreeChargedLeptonProperties.find(std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3));
if ( it != theThreeChargedLeptonProperties.end() )
return it->second;
ostringstream ids;
ids << "ChargedLepton" << id1 << id2 << id3;
return theThreeChargedLeptonProperties[std::tuple<unsigned int,unsigned int,unsigned int>(id1,id2,id3)] =
TripleProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Fourjet properties
*/
ObjectProperties& fourJetProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3, const unsigned int id4) {
map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties>::iterator it =
theFourJetProperties.find(std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>(id1,id2,id3,id4));
if ( it != theFourJetProperties.end() )
return it->second;
ostringstream ids;
ids << "Jet" << id1 << id2 << id3 << id4;
return theFourJetProperties[std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>(id1,id2,id3,id4)] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Four electroweak properties
*/
ObjectProperties& fourEWIDProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3, const unsigned int id4) {
map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties>::iterator it =
theFourEWIDProperties.find(std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>(id1,id2,id3,id4));
if ( it != theFourEWIDProperties.end() )
return it->second;
ostringstream ids;
ids << "EWID" << id1 << id2 << id3 << id4;
return theFourEWIDProperties[std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>(id1,id2,id3,id4)] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Four charged lepton properties
*/
ObjectProperties& fourChargedLeptonProperties(const unsigned int id1, const unsigned int id2,
const unsigned int id3, const unsigned int id4) {
map<std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>,ObjectProperties>::iterator it =
theFourChargedLeptonProperties.find(std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>(id1,id2,id3,id4));
if ( it != theFourChargedLeptonProperties.end() )
return it->second;
ostringstream ids;
ids << "ChargedLepton" << id1 << id2 << id3 << id4;
return theFourChargedLeptonProperties[std::tuple<unsigned int,unsigned int,unsigned int,unsigned int>(id1,id2,id3,id4)] =
ObjectProperties(ids.str(),generator()->maximumCMEnergy());
}
/**
* Perform any additional analysis required
*/
virtual void analyzeSpecial(long, double) {}
/**
* Append any additional histograms to the given histogram element
*/
virtual void finalize(XML::Element&) {}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
LeptonsJetsAnalysis & operator=(const LeptonsJetsAnalysis &) = delete;
};
}
#endif /* Herwig_LeptonsJetsAnalysis_H */
diff --git a/Analysis/TTJetsAnalysis.cc b/Analysis/TTJetsAnalysis.cc
--- a/Analysis/TTJetsAnalysis.cc
+++ b/Analysis/TTJetsAnalysis.cc
@@ -1,78 +1,76 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the TTJetsAnalysis class.
//
#include "TTJetsAnalysis.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
TTJetsAnalysis::TTJetsAnalysis() {}
-TTJetsAnalysis::~TTJetsAnalysis() {}
-
IBPtr TTJetsAnalysis::clone() const {
return new_ptr(*this);
}
IBPtr TTJetsAnalysis::fullclone() const {
return new_ptr(*this);
}
void TTJetsAnalysis::reconstructHardObjects(ParticleVector& parts) {
ParticleVector::iterator t = parts.begin();
for ( ; t != parts.end(); ++t ) {
if ( (**t).id() == ParticleID::t )
break;
}
if ( t == parts.end() )
throw Exception() << "No ttbar pair found in TTJetsAnalysis"
<< Exception::abortnow;
hardObjectMomentum("T") = (**t).momentum();
parts.erase(t);
ParticleVector::iterator tbar = parts.begin();
for ( ; tbar != parts.end(); ++tbar ) {
if ( (**tbar).id() == ParticleID::tbar )
break;
}
if ( tbar == parts.end() )
throw Exception() << "No ttbar pair found in TTJetsAnalysis"
<< Exception::abortnow;
hardObjectMomentum("Tbar") = (**tbar).momentum();
parts.erase(tbar);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void TTJetsAnalysis::persistentOutput(PersistentOStream &) const {}
void TTJetsAnalysis::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<TTJetsAnalysis,Herwig::JetsPlusAnalysis>
describeHerwigTTJetsAnalysis("Herwig::TTJetsAnalysis", "JetCuts.so HwJetsAnalysis.so");
void TTJetsAnalysis::Init() {
static ClassDocumentation<TTJetsAnalysis> documentation
("There is no documentation for the TTJetsAnalysis class");
}
diff --git a/Analysis/TTJetsAnalysis.h b/Analysis/TTJetsAnalysis.h
--- a/Analysis/TTJetsAnalysis.h
+++ b/Analysis/TTJetsAnalysis.h
@@ -1,106 +1,98 @@
// -*- C++ -*-
#ifndef Herwig_TTJetsAnalysis_H
#define Herwig_TTJetsAnalysis_H
//
// This is the declaration of the TTJetsAnalysis class.
//
#include "Herwig/Analysis/JetsPlusAnalysis.h"
namespace Herwig {
using namespace ThePEG;
/**
* Here is the documentation of the TTJetsAnalysis class.
*
* @see \ref TTJetsAnalysisInterfaces "The interfaces"
* defined for TTJetsAnalysis.
*/
class TTJetsAnalysis: public Herwig::JetsPlusAnalysis {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
TTJetsAnalysis();
- /**
- * The destructor.
- */
- virtual ~TTJetsAnalysis();
- //@}
-
public:
/**
* Reconstruct the desired electroweak objects and fill the
* respective momenta. Remove the reconstructed particles from the
* list.
*/
virtual void reconstructHardObjects(ParticleVector&);
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.
*/
TTJetsAnalysis & operator=(const TTJetsAnalysis &) = delete;
};
}
#endif /* Herwig_TTJetsAnalysis_H */
diff --git a/Analysis/ZJetsAnalysis.cc b/Analysis/ZJetsAnalysis.cc
--- a/Analysis/ZJetsAnalysis.cc
+++ b/Analysis/ZJetsAnalysis.cc
@@ -1,79 +1,77 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the ZJetsAnalysis class.
//
#include "ZJetsAnalysis.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
ZJetsAnalysis::ZJetsAnalysis() {}
-ZJetsAnalysis::~ZJetsAnalysis() {}
-
IBPtr ZJetsAnalysis::clone() const {
return new_ptr(*this);
}
IBPtr ZJetsAnalysis::fullclone() const {
return new_ptr(*this);
}
void ZJetsAnalysis::reconstructHardObjects(ParticleVector& parts) {
ParticleVector::iterator eplus = parts.begin();
for ( ; eplus != parts.end(); ++eplus ) {
if ( (**eplus).id() == ParticleID::eplus )
break;
}
if ( eplus == parts.end() )
throw Exception() << "No e+e- pair found in ZJetsAnalysis"
<< Exception::abortnow;
LorentzMomentum peplus = (**eplus).momentum();
parts.erase(eplus);
ParticleVector::iterator eminus = parts.begin();
for ( ; eminus != parts.end(); ++eminus ) {
if ( (**eminus).id() == ParticleID::eminus )
break;
}
if ( eminus == parts.end() )
throw Exception() << "No e+e- pair found in ZJetsAnalysis"
<< Exception::abortnow;
LorentzMomentum peminus = (**eminus).momentum();
parts.erase(eminus);
hardObjectMomentum("Z") = peplus + peminus;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void ZJetsAnalysis::persistentOutput(PersistentOStream &) const {}
void ZJetsAnalysis::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<ZJetsAnalysis,Herwig::JetsPlusAnalysis>
describeHerwigZJetsAnalysis("Herwig::ZJetsAnalysis", "JetCuts.so HwJetsAnalysis.so");
void ZJetsAnalysis::Init() {
static ClassDocumentation<ZJetsAnalysis> documentation
("There is no documentation for the ZJetsAnalysis class");
}
diff --git a/Analysis/ZJetsAnalysis.h b/Analysis/ZJetsAnalysis.h
--- a/Analysis/ZJetsAnalysis.h
+++ b/Analysis/ZJetsAnalysis.h
@@ -1,106 +1,98 @@
// -*- C++ -*-
#ifndef Herwig_ZJetsAnalysis_H
#define Herwig_ZJetsAnalysis_H
//
// This is the declaration of the ZJetsAnalysis class.
//
#include "Herwig/Analysis/JetsPlusAnalysis.h"
namespace Herwig {
using namespace ThePEG;
/**
* Here is the documentation of the ZJetsAnalysis class.
*
* @see \ref ZJetsAnalysisInterfaces "The interfaces"
* defined for ZJetsAnalysis.
*/
class ZJetsAnalysis: public Herwig::JetsPlusAnalysis {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
ZJetsAnalysis();
- /**
- * The destructor.
- */
- virtual ~ZJetsAnalysis();
- //@}
-
public:
/**
* Reconstruct the desired electroweak objects and fill the
* respective momenta. Remove the reconstructed particles from the
* list.
*/
virtual void reconstructHardObjects(ParticleVector&);
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.
*/
ZJetsAnalysis & operator=(const ZJetsAnalysis &) = delete;
};
}
#endif /* Herwig_ZJetsAnalysis_H */
diff --git a/Decay/Baryon/BaryonFactorizedDecayer.cc b/Decay/Baryon/BaryonFactorizedDecayer.cc
--- a/Decay/Baryon/BaryonFactorizedDecayer.cc
+++ b/Decay/Baryon/BaryonFactorizedDecayer.cc
@@ -1,809 +1,809 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the BaryonFactorizedDecayer class.
//
#include "BaryonFactorizedDecayer.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ParVector.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/PDT/DecayMode.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/RSSpinorWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/RSSpinorBarWaveFunction.h"
#include "Herwig/Decay/DecayVertex.h"
#include "ThePEG/Helicity/FermionSpinInfo.h"
#include "ThePEG/Helicity/RSFermionSpinInfo.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "Herwig/Decay/GeneralDecayMatrixElement.h"
using namespace Herwig;
using namespace ThePEG::Helicity;
BaryonFactorizedDecayer::BaryonFactorizedDecayer() {
// default values taken from PRD56, 2799
_a1c= 1.1;
_a2c=-0.5;
_a1b= 1.0;
_a2b= 0.28;
// intermediates
generateIntermediates(true);
}
void BaryonFactorizedDecayer::doinitrun() {
_current->initrun();
_form->initrun();
DecayIntegrator::doinitrun();
_weights.clear();_wgtloc.clear();_wgtmax.clear();
for(unsigned int ix=0;ix<numberModes();++ix) {
_wgtmax.push_back(mode(ix)->maxWeight());
_wgtloc.push_back(_weights.size());
for(unsigned int iy=0;iy<mode(ix)->channels().size();++iy)
_weights.push_back(mode(ix)->channels()[iy].weight());
}
}
void BaryonFactorizedDecayer::doinit() {
DecayIntegrator::doinit();
// get the CKM matrix (unsquared for interference)
Complex ckmmat[3][3];
vector< vector<Complex > > CKM(_theCKM->getUnsquaredMatrix(SM().families()));
for(unsigned int ix=0;ix<3;++ix) {
for(unsigned int iy=0;iy<3;++iy) {
ckmmat[ix][iy]=CKM[ix][iy];
}
}
// make sure the current and form factor got initialised
_current->init();
_form->init();
// find all the possible modes
vector<unsigned int> tformmap,tcurrmap;
vector<int> inquark,outquark,currq,curra;
tPDVector incoming;
vector<tPDVector> outgoing;
for(unsigned int iform=0;iform<_form->numberOfFactors();++iform) {
// particles from the form factor
int id0,id1;
_form->particleID (iform,id0,id1);
int spect1,spect2,inq,outq,ispin,ospin;
_form->formFactorInfo(iform,ispin,ospin,spect1,spect2,inq,outq);
// particles from the form factor
tPDPtr in = getParticleData(id0);
tPDPtr out = getParticleData(id1);
// the charge of the decay products
int Wcharge = in->iCharge()-out->iCharge();
// max mass for the particles in the current
Energy min = in->massMax()-out->massMin();
for(unsigned int icurr=0;icurr<_current->numberOfModes();++icurr) {
// get the particles from the current
int iq,ia;
_current->decayModeInfo(icurr,iq,ia);
tPDVector ptemp=_current->particles(Wcharge,icurr,iq,ia);
tPDVector outV = {out};
outV.insert(std::end(outV), std::begin(ptemp), std::end(ptemp));
Energy minb=ZERO;
for(unsigned int iz=0;iz<ptemp.size();++iz) minb+=ptemp[iz]->massMin();
// valid mode
if(outV.size()>1&&minb<min&&
(Wcharge!=0||(Wcharge==0&&((inq>0&&inq%2!=iq%2)||
(inq<0&&abs(inq)%2!=abs(ia)%2))))) {
tformmap.push_back(iform);tcurrmap.push_back(icurr);
incoming.push_back(in);
outgoing.push_back(outV);
inquark.push_back(inq);outquark.push_back(outq);
currq.push_back(iq);curra.push_back(ia);
}
// if the meson is neutral try the CC mode
if(Wcharge==0&&iq!=-ia&&((inq>0&&inq%2!=iq%2)||
(inq<0&&abs(inq)%2!=abs(ia)%2))) {
ptemp=_current->particles(Wcharge,icurr,-ia,-iq);
tPDVector outV = {out};
outV.insert(std::end(outV), std::begin(ptemp), std::end(ptemp));
Energy minb=ZERO;
for(unsigned int iz=0;iz<ptemp.size();++iz) minb+=ptemp[iz]->massMin();
if(outV.size()>1&&minb<min) {
tformmap.push_back(iform);tcurrmap.push_back(icurr);
incoming.push_back(in);
outgoing.push_back(outV);
inquark.push_back(inq);outquark.push_back(outq);
currq.push_back(-ia);curra.push_back(-iq);
}
}
}
}
_formmap.clear();
_currentmap.clear();
// loop over the modes and find the dupliciates
for(unsigned int ix=0;ix<outgoing.size();++ix) {
while(true) {
if ( outgoing[ix].empty() ) break;
vector<unsigned int> modeloc;
vector<bool> modecc;
findModes(ix,incoming,outgoing,modeloc,modecc);
// if more than two outgoing particles only allow one diagram
if ( outgoing[ix].size() > 2 && !modeloc.empty() ) {break;}
// create the mode and set the particles as for the first instance
PhaseSpaceModePtr mode=new_ptr(PhaseSpaceMode(incoming[ix],outgoing[ix],1.));
PhaseSpaceChannel channel((PhaseSpaceChannel(mode),0,1));
Energy min = incoming[ix]->massMax()-outgoing[ix][0]->massMin();
int Wcharge = incoming[ix]->iCharge()-outgoing[ix][0]->iCharge();
bool done = _current->createMode(Wcharge,tcPDPtr(),FlavourInfo(),
tcurrmap[ix],mode,1,0,channel,min);
if(!done){throw InitException() << "Failed to construct mode in "
<< "BaryonFactorizedDecayer::doinit()."
<< Exception::abortnow;}
// set the parameters for the additional modes
vector<unsigned int>ttform,ttcurr;
ttform.push_back(tformmap[ix]);ttcurr.push_back(tcurrmap[ix]);
for(unsigned int iy=0;iy<modeloc.size();++iy) {
ttform.push_back(tformmap[modeloc[iy]]);
ttcurr.push_back(tcurrmap[modeloc[iy]]);
}
- vector<Complex> tCKM; Complex ckm;
+ vector<Complex> tCKM;
for(unsigned int iy=0;iy<ttcurr.size();++iy) {
// get the quarks involved in the process
int iq,ia,inq,outq;
if(iy==0) {
iq=currq[ix];
ia=curra[ix];
inq=inquark[ix];
outq=outquark[ix];
}
else {
if(!modecc[iy-1]) {
iq=currq[modeloc[iy-1]];
ia=curra[modeloc[iy-1]];
inq=inquark[modeloc[iy-1]];
outq=outquark[modeloc[iy-1]];
}
else {
ia=-currq[modeloc[iy-1]];
iq=-curra[modeloc[iy-1]];
inq=-inquark[modeloc[iy-1]];
outq=-outquark[modeloc[iy-1]];
}
}
int id0,id1;
_form->particleID(ttform[iy],id0,id1);
int Wcharge = getParticleData(id0)->iCharge()-getParticleData(id1)->iCharge();
Complex ckm=1.;
if(Wcharge!=0) {
if(abs(iq)%2==0){ckm *= conj(ckmmat[abs(iq)/2-1][(abs(ia)-1)/2]);}
else{ckm *= conj(ckmmat[abs(ia)/2-1][(abs(iq)-1)/2]);}
if(abs(inq)%2==0){ckm *= ckmmat[abs(inq)/2-1][(abs(outq)-1)/2];}
else{ckm *= ckmmat[abs(outq)/2-1][(abs(inq)-1)/2];}
if(abs(inq)==5){ckm*=_a1b;}
else{ckm*=_a1c;}
}
else {
if(inq>0) {
if(abs(inq)%2==0){ckm *= ckmmat[abs(inq)/2-1][(abs(iq)-1)/2];}
else{ckm *= ckmmat[abs(iq)/2-1][(abs(inq)-1)/2];}
if(abs(outq)%2==0)
{ckm *= conj(ckmmat[abs(outq)/2-1][(abs(ia)-1)/2]);}
else{ckm *= conj(ckmmat[abs(ia)/2-1][(abs(outq)-1)/2]);}
}
else {
if(abs(inq)%2==0){ckm *= ckmmat[abs(inq)/2-1][(abs(ia)-1)/2];}
else{ckm *= ckmmat[abs(ia)/2-1][(abs(inq)-1)/2];}
if(abs(outq)%2==0)
{ckm *= conj(ckmmat[abs(outq)/2-1][(abs(iq)-1)/2]);}
else{ckm *= conj(ckmmat[abs(iq)/2-1][(abs(outq)-1)/2]);}
}
if(abs(inq)==5){ckm*=_a2b;}
else{ckm*=_a2c;}
}
if((abs(inq)%2==0&&inq<0)||(abs(inq)%2!=0&&inq>0)){ckm=conj(ckm);}
tCKM.push_back(ckm);
}
// add the parameters for the mode to the list
_currentmap.push_back(ttcurr);
_formmap.push_back(ttform);
_factCKM.push_back(tCKM);
double maxweight(0.);
// add the mode to the list
if(_wgtmax.size()>numberModes()) maxweight=_wgtmax[numberModes()];
// the weights for the channel
vector<double> channelwgts;
if(_wgtloc.size()>numberModes()&&
_wgtloc[numberModes()]+mode->channels().size()<=_weights.size()) {
vector<double>::iterator start=_weights.begin()+_wgtloc[numberModes()];
vector<double>::iterator end = start+mode->channels().size();
channelwgts=vector<double>(start,end);
}
else {
channelwgts.resize(mode->channels().size(),1./(mode->channels().size()));
}
// don't need channels for two body decays
if(outgoing[ix].size()==2) {
channelwgts.clear();
mode = new_ptr(PhaseSpaceMode(incoming[ix],outgoing[ix],maxweight));
}
else {
mode->maxWeight(maxweight);
mode->setWeights(channelwgts);
}
addMode(mode);
// resize the duplicate modes to remove them
for(unsigned int iy=0;iy<modeloc.size();++iy) outgoing[modeloc[iy]]=tPDVector();
break;
}
}
}
bool BaryonFactorizedDecayer::accept(tcPDPtr parent, const tPDVector & children) const {
bool allowed=false;
unsigned int iform(0),ix;
int idin(parent->id()),ibaryon,foundb,id0,id1;
vector<int> idall,idother;
tPDVector::const_iterator pit = children.begin();
tPDVector::const_iterator pend = children.end();
for( ; pit!=pend;++pit){idall.push_back((**pit).id());}
// loop over the particles in the form factor
do {
_form->particleID(iform,id0,id1);
ibaryon=0;
if(id0==idin){ibaryon=id1;}
else if(id0==-idin){ibaryon=-id1;}
if(ibaryon!=0) {
foundb=false;
idother.clear();
for(ix=0;ix<idall.size();++ix) {
if(idall[ix]==ibaryon){foundb=true;}
else{idother.push_back(idall[ix]);}
}
if(foundb){allowed=_current->accept(idother);}
}
++iform;
}
while(!allowed&&iform<_form->numberOfFactors());
return allowed;
}
int BaryonFactorizedDecayer::modeNumber(bool & cc,tcPDPtr parent,
const tPDVector & children) const {
unsigned int ix,iy;
int idin(parent->id()),ibaryon,foundb,id0,id1,icurr(-1),iform(0);
vector<int> idall,idother;
tPDVector::const_iterator pit = children.begin();
tPDVector::const_iterator pend = children.end();
for( ; pit!=pend;++pit){idall.push_back((**pit).id());}
// loop over the particles in the form factor
do
{
_form->particleID(iform,id0,id1);
ibaryon=0;
if(id0==idin){ibaryon=id1;}
else if(id0==-idin){ibaryon=-id1;}
++iform;
foundb=false;
idother.clear();
for(ix=0;ix<idall.size();++ix)
{
if(idall[ix]==ibaryon){foundb=true;}
else{idother.push_back(idall[ix]);}
}
if(foundb){icurr=_current->decayMode(idother);}
}
while(icurr<0&&iform<int(_form->numberOfFactors()));
// now find the mode
int imode=-1;
ix=0;
--iform;
do
{
for(iy=0;iy<_currentmap[ix].size();++iy)
{if(int(_currentmap[ix][iy])==icurr&&int(_formmap[ix][iy])==iform){imode=ix;}}
++ix;
}
while(imode<0&&ix<numberModes());
if(imode<0){throw DecayIntegratorError() << "Unable to find the mode in "
<< "BaryonFactorizedDecayer::decay()"
<< Exception::abortnow;}
// generate the mode
cc=id0!=idin;
return imode;
}
void BaryonFactorizedDecayer::persistentOutput(PersistentOStream & os) const {
os << _current << _form << _a1b << _a2b <<_a1c <<_a2c
<< _currentmap << _formmap << _factCKM << _wgtloc << _wgtmax << _weights
<< _theCKM;
}
void BaryonFactorizedDecayer::persistentInput(PersistentIStream & is, int) {
is >> _current >> _form >> _a1b >> _a2b >>_a1c >>_a2c
>> _currentmap >> _formmap >> _factCKM >> _wgtloc >> _wgtmax >> _weights
>> _theCKM;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<BaryonFactorizedDecayer,DecayIntegrator>
describeHerwigBaryonFactorizedDecayer("Herwig::BaryonFactorizedDecayer", "HwBaryonDecay.so");
void BaryonFactorizedDecayer::Init() {
static ClassDocumentation<BaryonFactorizedDecayer> documentation
("The BaryonFactorizedDecayer class combines the baryon form factor and a"
" weak current to perform a decay in the naive factorization approximation.");
static Reference<BaryonFactorizedDecayer,WeakCurrent> interfaceWeakCurrent
("Current",
"The reference for the decay current to be used.",
&BaryonFactorizedDecayer::_current, false, false, true, false, false);
static ParVector<BaryonFactorizedDecayer,int> interfaceWeightLocation
("WeightLocation",
"The locations of the weights for a given channel in the vector",
&BaryonFactorizedDecayer::_wgtloc,
0, 0, 0, 0, 10000, false, false, true);
static ParVector<BaryonFactorizedDecayer,double> interfaceWeightMax
("MaximumWeight",
"The maximum weight for a given channel.",
&BaryonFactorizedDecayer::_wgtmax,
0, 0, 0, 0., 100., false, false, true);
static ParVector<BaryonFactorizedDecayer,double> interfaceWeights
("Weights",
"The weights for the integration.",
&BaryonFactorizedDecayer::_weights,
0, 0, 0, 0., 1., false, false, true);
static Reference<BaryonFactorizedDecayer,BaryonFormFactor> interfaceFormFactor
("FormFactor",
"The form-factor",
&BaryonFactorizedDecayer::_form, true, true, true, false, false);
static Parameter<BaryonFactorizedDecayer,double> interfacea1Bottom
("a1Bottom",
"The factorization paramter a_1 for decays of bottom baryons",
&BaryonFactorizedDecayer::_a1b, 1., -10.0, 10.0,
false, false, true);
static Parameter<BaryonFactorizedDecayer,double> interfacea2Bottom
("a2Bottom",
"The factorization paramter a_2 for decays of bottom baryons",
&BaryonFactorizedDecayer::_a2b, 0.28, -10.0, 10.0,
false, false, true);
static Parameter<BaryonFactorizedDecayer,double> interfacea1Charm
("a1Charm",
"The factorization paramter a_1 for decays of charm baryons",
&BaryonFactorizedDecayer::_a1c, 1.1, -10.0, 10.0,
false, false, true);
static Parameter<BaryonFactorizedDecayer,double> interfacea2Charm
("a2Charm",
"The factorization paramter a_2 for decays of charm baryons",
&BaryonFactorizedDecayer::_a2c, -0.5, -10.0, 10.0,
false, false, true);
static Reference<BaryonFactorizedDecayer,StandardCKM> interfaceCKM
("CKM",
"Reference to the Standard Model object",
&BaryonFactorizedDecayer::_theCKM, false, false, true, false);
}
void BaryonFactorizedDecayer::
constructSpinInfo(const Particle & part, ParticleVector decay) const {
// for the decaying particle
if(part.id()>0) {
SpinorWaveFunction::
constructSpinInfo(_inHalf,const_ptr_cast<tPPtr>(&part),incoming,true);
}
else {
SpinorBarWaveFunction::
constructSpinInfo(_inHalfBar,const_ptr_cast<tPPtr>(&part),incoming,true);
}
// decay product
// spin 1/2
if(decay[0]->dataPtr()->iSpin()==PDT::Spin1Half) {
if(part.id()>0) {
SpinorBarWaveFunction::constructSpinInfo(_inHalfBar,decay[0],outgoing,true);
}
else {
SpinorWaveFunction::constructSpinInfo(_inHalf,decay[0],outgoing,true);
}
}
// spin 3/2
else if(decay[0]->dataPtr()->iSpin()==PDT::Spin3Half) {
if(part.id()>0) {
RSSpinorBarWaveFunction::constructSpinInfo(_inThreeHalfBar,
decay[0],outgoing,true);
}
else {
RSSpinorWaveFunction::constructSpinInfo(_inThreeHalf,
decay[0],outgoing,true);
}
}
else
assert(false);
// and the stuff from the current
_current->constructSpinInfo(ParticleVector(decay.begin()+1,decay.end()));
}
double BaryonFactorizedDecayer::me2(const int ichan, const Particle & part,
const tPDVector & outgoing,
const vector<Lorentz5Momentum> & momenta,
MEOption meopt) const {
double me(0.);
assert(part.dataPtr()->iSpin()==PDT::Spin1Half);
if(outgoing[0]->iSpin()==PDT::Spin1Half)
me=halfHalf(ichan,part,outgoing,momenta,meopt);
else if(outgoing[0]->iSpin()==PDT::Spin3Half)
me=halfThreeHalf(ichan,part,outgoing,momenta,meopt);
else
assert(false);
return me;
}
// matrix element for a 1/2 -> 1/2 decay
double BaryonFactorizedDecayer::halfHalf(const int ichan, const Particle & part,
const tPDVector & outgoing,
const vector<Lorentz5Momentum> & momenta,
MEOption meopt) const {
Energy scale;
// extract the spins of the particles
vector<PDT::Spin> spin;
for(unsigned ix=0;ix<outgoing.size();++ix)
spin.push_back(outgoing[ix]->iSpin());
if(!ME())
ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,spin)));
if(meopt==Initialize) {
// spinors and rho
if(part.id()>0)
SpinorWaveFunction ::calculateWaveFunctions(_inHalf,_rho,
const_ptr_cast<tPPtr>(&part),
incoming);
else
SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho,
const_ptr_cast<tPPtr>(&part),
incoming);
}
ME()->zero();
// spinors for the decay product
if(part.id()>0) {
_inHalfBar.resize(2);
for(unsigned int ihel=0;ihel<2;++ihel)
_inHalfBar[ihel] = HelicityFunctions::dimensionedSpinorBar(-momenta[0],ihel,Helicity::outgoing);
}
else {
_inHalf.resize(2);
for(unsigned int ihel=0;ihel<2;++ihel)
_inHalf[ihel] = HelicityFunctions::dimensionedSpinor (-momenta[0],ihel,Helicity::outgoing);
}
// get the information on the form-factor
int id0(part.id()),id1(outgoing[0]->id());
// work out the value of q and calculate the form factors
Lorentz5Momentum q(part.momentum()-momenta[0]);
q.rescaleMass();
Energy m0(part.mass()),m1(momenta[0].mass());
Energy2 q2(q.mass2());
Lorentz5Momentum sum(part.momentum()+momenta[0]);
// calculate the baryonic part of the current for the decay
double pre(0.);
for(unsigned int mode=0;mode<_formmap[imode()].size();++mode) {
Complex f1v,f2v,f3v,f1a,f2a,f3a;
// calculate the form factor piece
_form->SpinHalfSpinHalfFormFactor(q2,_formmap[imode()][mode],id0,id1,m0,m1,
f1v,f2v,f3v,f1a,f2a,f3a,FlavourInfo());
Complex left = f1v-f1a-f2v-double((m0-m1)/(m0+m1))*f2a;
Complex right = f1v+f1a-f2v+double((m0-m1)/(m0+m1))*f2a;
vector<LorentzPolarizationVectorE> baryon(4);
for(unsigned int ix=0;ix<2;++ix) {
for(unsigned int iy=0;iy<2;++iy) {
LorentzPolarizationVectorE
vtemp = _inHalf[ix].generalCurrent(_inHalfBar[iy],left,right);
complex<Energy> vspin=_inHalf[ix].scalar(_inHalfBar[iy]);
complex<Energy> aspin=_inHalf[ix].pseudoScalar(_inHalfBar[iy]);
// the momentum like pieces
if(part.id()>0) {
vtemp+= (f2v*vspin+f2a*aspin)/(m0+m1)*sum;
vtemp+= (f3v*vspin+f3a*aspin)/(m0+m1)*q;
}
else {
vtemp+= (f2v*vspin-f2a*aspin)/(m0+m1)*sum;
vtemp+= (f3v*vspin-f3a*aspin)/(m0+m1)*q;
}
if(part.id()>0) baryon[2*ix+iy]=vtemp;
else baryon[2*iy+ix]=vtemp;
}
}
// construct the weak current
vector<LorentzPolarizationVectorE> hadron =
_current->current(tcPDPtr(),FlavourInfo(),
_currentmap[imode()][mode],ichan,scale,
tPDVector(outgoing.begin()+1,outgoing.end()),
vector<Lorentz5Momentum>(momenta.begin()+1,momenta.end()),meopt);
pre=pow(part.mass()/scale,int(outgoing.size()-3));pre*=pre;
vector<unsigned int> constants(outgoing.size()+1),ihel(outgoing.size()+1);
int itemp=1;
unsigned int ibar=0;
for(int iz=int(outgoing.size()-1);iz>=0;--iz) {
if(abs(outgoing[iz]->id())!=id1) {
itemp *= outgoing[iz]->iSpin();
constants[iz]=itemp;
}
else ibar=iz;
constants[outgoing.size()]=1;
constants[ibar]=constants[ibar+1];
}
for(unsigned int mhel=0;mhel<baryon.size();++mhel) {
ihel[0 ]=mhel/2;
ihel[ibar+1]=mhel%2;
for(unsigned int lhel=0;lhel<hadron.size();++lhel) {
// map the index for the hadrons to a helicity state
for(unsigned int ix=outgoing.size();ix>0;--ix) {
if(ix-1!=ibar){ihel[ix]=(lhel%constants[ix-1])/constants[ix];}}
(*ME())(ihel) += Complex(hadron[lhel].dot(baryon[mhel])*
_factCKM[imode()][mode]*SM().fermiConstant());
}
}
}
// return the answer
return 0.5*pre*(ME()->contract(_rho)).real();
}
// matrix element for a 1/2 -> 3/2 decay
double BaryonFactorizedDecayer::halfThreeHalf(const int ichan, const Particle & part,
const tPDVector & outgoing,
const vector<Lorentz5Momentum> & momenta,
MEOption meopt) const {
// spins
Energy scale;
vector<PDT::Spin> spin(outgoing.size());
for(unsigned int ix=0;ix<outgoing.size();++ix)
spin[ix]=outgoing[ix]->iSpin();
if(!ME())
ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1Half,spin)));
// spinors etc for the decaying particle
if(meopt==Initialize) {
// spinors and rho
if(part.id()>0)
SpinorWaveFunction ::calculateWaveFunctions(_inHalf,_rho,
const_ptr_cast<tPPtr>(&part),
incoming);
else
SpinorBarWaveFunction::calculateWaveFunctions(_inHalfBar,_rho,
const_ptr_cast<tPPtr>(&part),
incoming);
}
ME()->zero();
// spinors for the decay product
LorentzPolarizationVector in=UnitRemoval::InvE*part.momentum();
if(part.id()>0) {
RSSpinorBarWaveFunction swave(momenta[0],outgoing[0],Helicity::outgoing);
_inThreeHalfBar.resize(4);
_inHalfBar.resize(4);
for(unsigned int ihel=0;ihel<4;++ihel) {
swave.reset(ihel);
_inThreeHalfBar[ihel]=swave.dimensionedWf();
_inHalfBar[ihel] = _inThreeHalfBar[ihel].dot(in);
}
}
else {
RSSpinorWaveFunction swave(momenta[0],outgoing[0],Helicity::outgoing);
_inThreeHalf.resize(4);
_inHalf.resize(4);
for(unsigned int ihel=0;ihel<4;++ihel) {
swave.reset(ihel);
_inThreeHalf[ihel]=swave.dimensionedWf();
_inHalf[ihel] = _inThreeHalf[ihel].dot(in);
}
}
// get the information on the form-factor
int id0(part.id()),id1(outgoing[0]->id());
// work out the value of q and calculate the form factors
Lorentz5Momentum q(part.momentum()-momenta[0]);
q.rescaleMass();
Energy m0(part.mass()),m1(momenta[0].mass());
Energy2 q2(q.mass2());
Lorentz5Momentum sum(part.momentum()+momenta[0]);
InvEnergy ms(1./(m0+m1));
InvEnergy2 ms2(ms*ms);
double pre(0.);
for(unsigned int mode=0;mode<_formmap[imode()].size();++mode) {
// calculate the form factors
Complex f1v,f2v,f3v,f4v,f1a,f2a,f3a,f4a;
_form->SpinHalfSpinThreeHalfFormFactor(q2,_formmap[imode()][mode],id0,id1,m0,m1,
f1v,f2v,f3v,f4v,f1a,f2a,f3a,f4a,FlavourInfo());
complex<InvEnergy2> lS1,lS2,rS1,rS2;
Complex left,right;
complex<InvEnergy> lV,rV;
if(part.id()>0) {
left = f1a-f1v;
right = f1a+f1v;
lS1 = ms2*(f3a-f4a-f3v+f4v);
rS1 = ms2*(f3a-f4a+f3v-f4v);
lS2 = ms2*(f4a-f4v);
rS2 = ms2*(f4a+f4v);
lV = ms*(f2a-f2v);
rV = ms*(f2a+f2v);
}
else {
left = conj(f1a+f1v);
right = conj(f1a-f1v);
lS1 = ms2*conj(f3a-f4a+f3v-f4v);
rS1 = ms2*conj(f3a-f4a-f3v+f4v);
lS2 = ms2*conj(f4a-f4v);
rS2 = ms2*conj(f4a+f4v);
lV = ms *conj(f2a-f2v);
rV = ms *conj(f2a+f2v);
}
// construct the vectors for the decay
LorentzPolarizationVectorE baryon[4][2];
for(unsigned int iya=0;iya<4;++iya) {
for(unsigned int ixa=0;ixa<2;++ixa) {
unsigned int ix,iy;
if(outgoing[0]->id()>0) {
ix=iya;
iy=ixa;
}
else {
ix=ixa;
iy=iya;
}
// scalar like terms
complex<Energy> lfact = _inHalf[iy].leftScalar( _inHalfBar[ix]);
complex<Energy> rfact = _inHalf[iy].rightScalar(_inHalfBar[ix]);
Complex scalar1 = (lS1*lfact+rS1*rfact)*UnitRemoval::E;
Complex scalar2 = (lS2*lfact+rS2*rfact)*UnitRemoval::E;
LorentzPolarizationVector svec = _inHalf[iy].generalCurrent(_inHalfBar[ix],lV/ms,rV/ms)*ms;
LorentzPolarizationVectorE tvec;
if(part.id()>0) {
tvec=_inThreeHalfBar[ix].generalCurrent(_inHalf[iy],left,right);
}
else {
tvec=_inThreeHalf[iy].generalCurrent(_inHalfBar[ix],left,right);
}
baryon[iya][ixa] = tvec+svec*UnitRemoval::E
+scalar1*momenta[0]+scalar2*part.momentum();
}
}
vector<LorentzPolarizationVectorE> hadron =
_current->current(tcPDPtr(),FlavourInfo(),_currentmap[imode()][mode],ichan,scale,
tPDVector(outgoing.begin()+1,outgoing.end()),
vector<Lorentz5Momentum>(momenta.begin()+1,momenta.end()),meopt);
// prefactor
pre = pow(part.mass()/scale,int(outgoing.size()-3));
pre *= pre;
// work out the mapping for the hadron vector
vector<unsigned int> constants(outgoing.size()+1),ihel(outgoing.size()+1);
int itemp = 1;
int ibar = 0;
for(int ix=int(outgoing.size()-1);ix>=0;--ix) {
if(abs(outgoing[ix]->id())!=id1) {
itemp*=outgoing[ix]->iSpin();
constants[ix]=itemp;
}
else{ibar=ix;}
}
constants[outgoing.size()]=1;
constants[ibar]=constants[ibar+1];
for(unsigned int iya=0;iya<4;++iya) {
ihel[1]=iya;
for(unsigned int ixa=0;ixa<2;++ixa) {
ihel[0]=ixa;
for(unsigned int lhel=0;lhel<hadron.size();++lhel) {
// map the index for the hadrons to a helicity state
for(int ix=int(outgoing.size());ix>0;--ix)
{if(ix-1!=ibar){ihel[ix]=(lhel%constants[ix-1])/constants[ix];}}
(*ME())(ihel) += Complex(hadron[lhel].dot(baryon[iya][ixa])*
_factCKM[imode()][mode]*SM().fermiConstant());
}
}
}
}
// return the answer
return 0.5*pre*(ME()->contract(_rho)).real();
}
void BaryonFactorizedDecayer::findModes(unsigned int imode,
tPDVector & incoming,
vector<tPDVector> & outgoing,
vector<unsigned int> & loc,
vector<bool> & cc) {
// get the id's for the mode
// incoming
int id_in = incoming[imode]->id();
int idbar_in = incoming[imode]->CC() ?
incoming[imode]->CC()->id() : incoming[imode]->id();
// outgoing
vector<int> id_out,idbar_out;
for(unsigned int ix=0;ix<outgoing[imode].size();++ix) {
id_out.push_back(outgoing[imode][ix]->id());
if(outgoing[imode][ix]->CC())
idbar_out.push_back(outgoing[imode][ix]->CC()->id());
else
idbar_out.push_back(id_out[ix]);
}
// loop over the modes
for(unsigned int ix=0;ix<outgoing.size();++ix) {
if(ix==imode||outgoing[ix].empty()) continue;
assert(!outgoing[ix].empty());
assert(incoming[ix]);
// the particle mode
if(incoming[ix]->id()==id_in&&outgoing[ix].size()==id_out.size()) {
vector<bool> done(id_out.size(),false);
unsigned int nfound = 0;
for(unsigned int iy=0;iy<id_out.size();++iy) {
int idtemp = outgoing[ix][iy]->id();
unsigned int iz = 0;
bool found = false;
do {
if(idtemp==id_out[iz]&&!done[iz]) {
done[iz]=true;
found=true;
}
++iz;
}
while(iz<id_out.size()&&!found);
if(found) ++nfound;
}
if(nfound==id_out.size()) {
cc.push_back(false);
loc.push_back(ix);
}
}
// the charge conjugate mode
if(incoming[ix]->id()==idbar_in&&outgoing[ix].size()==idbar_out.size()) {
vector<bool> done(id_out.size(),false);
unsigned int nfound=0;
for(unsigned int iy=0;iy<idbar_out.size();++iy) {
int idtemp=outgoing[ix][iy]->id();
unsigned int iz=0;
bool found = false;
do {
if(idtemp==idbar_out[iz]&&!done[iz]) {
done[iz]=true;
found=true;
}
++iz;
}
while(iz<idbar_out.size()&&!found);
if(found) ++nfound;
}
if(nfound==idbar_out.size()) {
cc.push_back(false);
loc.push_back(ix);
}
}
}
}
// output the setup information for the particle database
void BaryonFactorizedDecayer::dataBaseOutput(ofstream & output, bool header) const {
unsigned int ix;
if(header){output << "update decayers set parameters=\"";}
DecayIntegrator::dataBaseOutput(output,false);
output << "newdef " << name() << ":a1Bottom " << _a1b << "\n";
output << "newdef " << name() << ":a2Bottom " << _a2b << "\n";
output << "newdef " << name() << ":a1Charm " << _a1c << "\n";
output << "newdef " << name() << ":a2Charm " << _a2c << "\n";
output << "newdef " << name() << ":CKM " << _theCKM->name() << " \n";
for(ix=0;ix<_wgtloc.size();++ix)
{output << "insert " << name() << ":WeightLocation " << ix << " "
<< _wgtloc[ix] << "\n";}
for(ix=0;ix<_wgtmax.size();++ix)
{output << "insert " << name() << ":MaximumWeight " << ix << " "
<< _wgtmax[ix] << "\n";}
for(ix=0;ix<_weights.size();++ix)
{output << "insert " << name() << ":Weights " << ix << " "
<< _weights[ix] << "\n";}
_current->dataBaseOutput(output,false,true);
output << "newdef " << name() << ":Current " << _current->name() << " \n";
_form->dataBaseOutput(output,false,true);
output << "newdef " << name() << ":FormFactor " << _form->name() << " \n";
if(header){output << "\n\" where BINARY ThePEGName=\"" << fullName() << "\";" << endl;}
}
diff --git a/Decay/BranchingRatioReweighter.cc b/Decay/BranchingRatioReweighter.cc
--- a/Decay/BranchingRatioReweighter.cc
+++ b/Decay/BranchingRatioReweighter.cc
@@ -1,81 +1,79 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the BranchingRatioReweighter class.
//
#include "BranchingRatioReweighter.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/EventRecord/Event.h"
#include "ThePEG/Handlers/EventHandler.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/EventRecord/StandardSelectors.h"
#include "ThePEG/Handlers/StandardEventHandler.h"
#include "Herwig/Utilities/EnumParticles.h"
using namespace Herwig;
BranchingRatioReweighter::BranchingRatioReweighter() {}
-BranchingRatioReweighter::~BranchingRatioReweighter() {}
-
void BranchingRatioReweighter::
handle(EventHandler & eh,const tPVector & ,const Hint & ) {
tEventPtr event = eh.currentEvent();
// weight
double weight = 1.;
// get all the particles
set<tcPPtr> particles;
event->select(inserter(particles),ThePEG::AllSelector());
for(set<tcPPtr>::const_iterator it=particles.begin();it!=particles.end();++it) {
// skip stable
if((**it).dataPtr()->stable()) continue;
// skip remnant and clusters
if((**it).id()==ParticleID::Remnant ||
(**it).id()==ParticleID::Cluster) continue;
// if spacelike skip
if((**it).mass()<ZERO) continue;
if(*it == event->incoming().first ||
*it == event->incoming().second ) continue;
// find unique particles
bool unique = true;
for(unsigned int ix=0;ix<(**it).children().size();++ix) {
if((**it).children()[ix]->id()==(**it).id()) {
unique = false;
break;
}
}
if(!unique) continue;
weight *= (**it).dataPtr()->decaySelector().sum();
}
// do the reweighting
if ( dynamic_cast<StandardEventHandler*>(&eh) ) {
StandardEventHandler& seh =
dynamic_cast<StandardEventHandler&>(eh);
seh.reweight(weight);
}
}
IBPtr BranchingRatioReweighter::clone() const {
return new_ptr(*this);
}
IBPtr BranchingRatioReweighter::fullclone() const {
return new_ptr(*this);
}
// The following static variable is needed for the type description system in ThePEG.
DescribeNoPIOClass<BranchingRatioReweighter,StepHandler>
describeHerwigBranchingRatioReweighter("Herwig::BranchingRatioReweighter", "Herwig.so");
void BranchingRatioReweighter::Init() {
static ClassDocumentation<BranchingRatioReweighter> documentation
("The BranchingRatioReweighter class reweights events if some"
" decay modes are switched off");
}
diff --git a/Decay/BranchingRatioReweighter.h b/Decay/BranchingRatioReweighter.h
--- a/Decay/BranchingRatioReweighter.h
+++ b/Decay/BranchingRatioReweighter.h
@@ -1,102 +1,94 @@
// -*- C++ -*-
#ifndef Herwig_BranchingRatioReweighter_H
#define Herwig_BranchingRatioReweighter_H
//
// This is the declaration of the BranchingRatioReweighter class.
//
#include "ThePEG/Handlers/StepHandler.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Decay
* The BranchingRatioReweighter class is designed to reweight events
* where some decay modes of a particle, or many particles, have been
* switched off in order to improve the statistics.
*
* @see \ref BranchingRatioReweighterInterfaces "The interfaces"
* defined for BranchingRatioReweighter.
*/
class BranchingRatioReweighter: public StepHandler {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
BranchingRatioReweighter();
- /**
- * The destructor.
- */
- virtual ~BranchingRatioReweighter();
- //@}
-
public:
/** @name Virtual functions required by the StepHandler class. */
//@{
/**
* The main function called by the EventHandler class to
* perform a step. Given the current state of an Event, this function
* performs the event generation step and includes the result in a new
* Step object int the Event record.
* @param eh the EventHandler in charge of the Event generation.
* @param tagged if not empty these are the only particles which should
* be considered by the StepHandler.
* @param hint a Hint object with possible information from previously
* performed steps.
* @throws Veto if the StepHandler requires the current step to be discarded.
* @throws Stop if the generation of the current Event should be stopped
* after this call.
* @throws Exception if something goes wrong.
*/
virtual void handle(EventHandler & eh, const tPVector & tagged,
const Hint & hint);
//@}
public:
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
BranchingRatioReweighter & operator=(const BranchingRatioReweighter &) = delete;
};
}
#endif /* Herwig_BranchingRatioReweighter_H */
diff --git a/Decay/Dalitz/DalitzResonance.h b/Decay/Dalitz/DalitzResonance.h
--- a/Decay/Dalitz/DalitzResonance.h
+++ b/Decay/Dalitz/DalitzResonance.h
@@ -1,156 +1,158 @@
// -*- C++ -*-
#ifndef Herwig_DalitzResonance_H
#define Herwig_DalitzResonance_H
//
// This is the declaration of the DalitzResonance class.
//
#include "ThePEG/Config/ThePEG.h"
#include "DalitzResonance.fh"
#include <cassert>
namespace Herwig {
using namespace ThePEG;
namespace ResonanceType {
/**
* Enum for the type of resonace
*/
enum Type {NonResonant=0,
Spin0=1,Spin1=3,Spin2=5,
Spin0E691=11,Spin1E691=13,Spin2E691=15,
BABARf0=21, Spin0Gauss=31, Flattef0=41, Spin0Complex=51,
Flattea0=61, FlatteKstar0=71,
Sigma=81,
Spin1GS=23,
Spin0NonResonant=101, Spin1NonResonant=103, Spin2NonResonant=105,
Spin0MIPWA=-1, PiPiI2=-11, KMatrix=-21, LASS=-31};
}
/**
* The DalitzResonance class provides a container class for
* information on resonances in multi-body dalitz decays.
*/
class DalitzResonance: public Base {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* The default constructor.
*/
- DalitzResonance() {}
+ DalitzResonance() : id(0), type(ResonanceType::NonResonant),mass(ZERO),width(ZERO),
+ daughter1(0),daughter2(0),spectator(0),amp(0.),R(ZERO)
+ {}
/**
* Constructor specifiying the parameters
*/
DalitzResonance(long pid, ResonanceType::Type rtype, Energy m, Energy w,
unsigned int d1, unsigned int d2, unsigned int s,
double mag, double phi, InvEnergy rr)
: id(pid), type(rtype), mass(m),width(w),
daughter1(d1),daughter2(d2),spectator(s),
amp(mag*exp(Complex(0,phi))), R(rr)
{}
//@}
public:
/**
* Return the Breit-Wigner times the form factor
*/
virtual Complex BreitWigner(const Energy & mAB, const Energy & mA, const Energy & mB) const;
/**
* Output the parameters
*/
virtual void dataBaseOutput(ofstream & output);
/**
* Read the parameters for a Dalitz resonance
*/
static DalitzResonancePtr readResonance(string arg, string & error);
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();
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DalitzResonance & operator=(const DalitzResonance &) = delete;
public:
/**
* PID of resonant particle
*/
long id;
/**
* Type of the resonance
*/
ResonanceType::Type type;
/**
* Mass of the resonance
*/
Energy mass;
/**
* Width of the resonance
*/
Energy width;
/**
* The children
*/
unsigned int daughter1,daughter2;
/**
* The spectactor
*/
unsigned int spectator;
/**
* The amplitude
*/
Complex amp;
/**
* Radius for the Ballt-Weisskopf formfactor
*/
InvEnergy R;
};
}
#endif /* Herwig_DalitzResonance_H */
diff --git a/Decay/Dalitz/ScalarTo3ScalarDalitz.cc b/Decay/Dalitz/ScalarTo3ScalarDalitz.cc
--- a/Decay/Dalitz/ScalarTo3ScalarDalitz.cc
+++ b/Decay/Dalitz/ScalarTo3ScalarDalitz.cc
@@ -1,174 +1,173 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the ScalarTo3ScalarDalitz class.
//
#include "ScalarTo3ScalarDalitz.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
#include "Herwig/Decay/GeneralDecayMatrixElement.h"
using namespace Herwig;
using namespace ThePEG::Helicity;
IBPtr ScalarTo3ScalarDalitz::clone() const {
return new_ptr(*this);
}
IBPtr ScalarTo3ScalarDalitz::fullclone() const {
return new_ptr(*this);
}
void ScalarTo3ScalarDalitz::persistentOutput(PersistentOStream & os) const {
os << useResonanceMass_ ;
}
void ScalarTo3ScalarDalitz::persistentInput(PersistentIStream & is, int) {
is >> useResonanceMass_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<ScalarTo3ScalarDalitz,DalitzBase>
describeHerwigScalarTo3ScalarDalitz("Herwig::ScalarTo3ScalarDalitz", "HwDalitzDecay.so");
void ScalarTo3ScalarDalitz::Init() {
static ClassDocumentation<ScalarTo3ScalarDalitz> documentation
("The ScalarTo3ScalarDalitz class provides a base class for "
"weak three-body decays of bottom and charm mesons");
static Switch<ScalarTo3ScalarDalitz,bool> interfaceResonanceMass
("ResonanceMass",
"Whether to use the kinematic mass or the resonance pole mass for the denominator in kinematic expressions",
&ScalarTo3ScalarDalitz::useResonanceMass_, false, false, false);
static SwitchOption interfaceResonanceMassYes
(interfaceResonanceMass,
"Yes",
"Use the resonance mass, to be avoided only use if do in experimental fit",
true);
static SwitchOption interfaceResonanceMassNo
(interfaceResonanceMass,
"No",
"Use the correct kinematic mass",
false);
}
void ScalarTo3ScalarDalitz::
constructSpinInfo(const Particle & part, ParticleVector decay) const {
// set up the spin information for the decay products
ScalarWaveFunction::constructSpinInfo(const_ptr_cast<tPPtr>(&part),
incoming,true);
for(unsigned int ix=0;ix<3;++ix)
ScalarWaveFunction::constructSpinInfo(decay[ix],outgoing,true);
}
double ScalarTo3ScalarDalitz::me2(const int ichan, const Particle & part,
const tPDVector & ,
const vector<Lorentz5Momentum> & momenta,
MEOption meopt) const {
- static const Complex ii(0.,1.);
if(!ME())
ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin0,PDT::Spin0,PDT::Spin0)));
useMe();
if(meopt==Initialize) {
ScalarWaveFunction::
calculateWaveFunctions(rho_,const_ptr_cast<tPPtr>(&part),incoming);
}
// set the kinematics
mD_ = part.mass();
for(unsigned int ix=0;ix<momenta.size();++ix) {
mOut_[ix]=momenta[ix].mass();
for(unsigned int iy=ix+1;iy<momenta.size();++iy) {
m2_[ix][iy]=(momenta[ix]+momenta[iy]).m();
m2_[iy][ix]=m2_[ix][iy];
}
}
// now compute the matrix element
Complex amp = amplitude(ichan);
(*ME())(0,0,0,0) = amp;
return norm(amp);
}
Complex ScalarTo3ScalarDalitz::resAmp(unsigned int i) const {
Complex output = resonances()[i]->amp;
if (resonances()[i]->type==ResonanceType::NonResonant) return output;
// mass of the resonance
const Energy & mR = resonances()[i]->mass ;
// locations of the outgoing particles
const unsigned int &d1 = resonances()[i]->daughter1;
const unsigned int &d2 = resonances()[i]->daughter2;
const unsigned int &sp = resonances()[i]->spectator;
// compute the Breit-Wigner times resonance form factor piece
output *= resonances()[i]->BreitWigner(m2_[d1][d2],mOut_[d1],mOut_[d2]);
// angular piece
// mass for the denominator
Energy mDen = useResonanceMass_ ? resonances()[i]->mass : m2_[d1][d2];
// denominator for the older form of the amplitude
Energy2 denom = GeV2;
if (resonances()[i]->type/10 == 1 ) {
Energy2 pa2 = 0.25*(sqr(m2_[d1][d2])-2.*(sqr(mOut_[d1])+sqr(mOut_[d2])) + sqr(sqr(mOut_[d1])-sqr(mOut_[d2]))/sqr(m2_[d1][d2]));
Energy2 pc2 = 0.25*(sqr(m2_[d1][d2])-2.*(sqr(mD_ )+sqr(mOut_[sp])) + sqr(sqr(mD_ )-sqr(mOut_[sp]))/sqr(m2_[d1][d2]));
denom = 4.*sqrt(pa2*pc2);
}
// vectors
if(abs(resonances()[i]->type)%10==3) {
output *= (sqr(m2_[d2][sp])-sqr(m2_[d1][sp])
+ ( sqr(mD_)-sqr(mOut_[sp]))*(sqr(mOut_[d1])-sqr(mOut_[d2]))/sqr(mDen) )/denom;
}
else if(abs(resonances()[i]->type)%10==5) {
output *= 1./sqr(denom)*( sqr( sqr(m2_[d2][sp]) - sqr(m2_[d1][sp]) +(sqr(mD_)-sqr(mOut_[sp]))*(sqr(mOut_[d1])-sqr(mOut_[d2]))/(sqr(mDen))) -
(sqr(m2_[d1][d2])-2* sqr(mD_)-2*sqr(mOut_[sp]) + sqr((sqr( mD_) - sqr(mOut_[sp]))/mDen))*
(sqr(m2_[d1][d2])-2*sqr(mOut_[d1])-2*sqr(mOut_[d2]) + sqr((sqr(mOut_[d1]) - sqr(mOut_[d2]))/mDen))/3.);
}
// spin zero and non-resonant is done now
if((abs(resonances()[i]->type)%10==1 && resonances()[i]->type != ResonanceType::Spin0Gauss ) ||
abs(resonances()[i]->type/10)==10) {
return output;
}
// spin piece x Blatt-Weisskopf for parent
else {
double fD=1.;
// for the D decay
Energy pD = sqrt(max(ZERO,(0.25*sqr(sqr(mD_)-sqr(mR)-sqr(mOut_[sp])) - sqr(mR*mOut_[sp]))/sqr(mD_)));
Energy pDAB= sqrt( 0.25*sqr(sqr(mD_)-sqr(m2_[d1][d2])-sqr(mOut_[sp])) - sqr(m2_[d1][d2]*mOut_[sp]))/mD_;
double r2A(parentRadius() *pD),r2B(parentRadius() *pDAB);
// Blatt-Weisskopf factors and spin piece
switch (resonances()[i]->type) {
case ResonanceType::Spin0Gauss:
fD = exp(-(r2B-r2A)/12.);
break;
case ResonanceType::Spin1: case ResonanceType::Spin1E691 : case ResonanceType::Spin1GS :
fD=sqrt( (1. + sqr(r2A)) / (1. + sqr(r2B)) );
break;
case ResonanceType::Spin2: case ResonanceType::Spin2E691:
fD = sqrt( (9. + sqr(r2A)*(3.+sqr(r2A))) / (9. + sqr(r2B)*(3.+sqr(r2B))));
break;
default :
assert(false);
}
output *= fD;
return output;
}
}
void ScalarTo3ScalarDalitz::dataBaseOutput(ofstream & output, bool header) const {
if(header) output << "update decayers set parameters=\"";
// parameters for the DalitzBase base class
DalitzBase::dataBaseOutput(output,false);
output << "newdef " << name() << ":ResonanceMass " << useResonanceMass_ << "\n";
output << "\n";
if(header) {
output << "\n\" where BINARY ThePEGName=\"" << fullName() << "\";" << endl;
}
}
diff --git a/Decay/EvtGen/EvtGenInterface.cc b/Decay/EvtGen/EvtGenInterface.cc
--- a/Decay/EvtGen/EvtGenInterface.cc
+++ b/Decay/EvtGen/EvtGenInterface.cc
@@ -1,1020 +1,1018 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the EvtGenInterface class.
//
#include "EvtGenInterface.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ParVector.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/DecayMode.h"
#include "Herwig/Decay/DecayVertex.h"
#include "Herwig/Decay/GeneralDecayMatrixElement.h"
#include "EvtGenBase/EvtRandom.hh"
#include "EvtGenBase/EvtAbsRadCorr.hh"
#include "EvtGenExternal/EvtExternalGenList.hh"
#include "EvtGenBase/EvtScalarParticle.hh"
#include "EvtGenBase/EvtDiracParticle.hh"
#include "EvtGenBase/EvtVectorParticle.hh"
#include "EvtGenBase/EvtRaritaSchwingerParticle.hh"
#include "EvtGenBase/EvtTensorParticle.hh"
#include "EvtGenBase/EvtStringParticle.hh"
#include "EvtGenBase/EvtHighSpinParticle.hh"
#include "EvtGenBase/EvtDecayTable.hh"
#ifndef EVTGEN_SHARE
#error Makefile.am needs to define EVTGEN_SHARE
#endif
using namespace Herwig;
namespace {
const string prefix=EVTGEN_SHARE "";
const string p8data=PYTHIA8DATA "";
}
EvtGenInterface::EvtGenInterface() : decayName_(prefix+"/DECAY_2010.DEC"),
pdtName_(prefix+"/evt.pdl"),
reDirect_(true), checkConv_(false),
p8Data_(p8data)
{}
EvtGenInterface::EvtGenInterface(const EvtGenInterface & x)
: Interfaced(x), decayName_(x.decayName_), pdtName_(x.pdtName_),
userDecays_(x.userDecays_), reDirect_(x.reDirect_),
checkConv_(x.checkConv_), convID_(x.convID_),
p8Data_(x.p8Data_), evtrnd_(x.evtrnd_),evtgen_(x.evtgen_)
{}
-EvtGenInterface::~EvtGenInterface() {}
-
IBPtr EvtGenInterface::clone() const {
return new_ptr(*this);
}
IBPtr EvtGenInterface::fullclone() const {
return new_ptr(*this);
}
void EvtGenInterface::persistentOutput(PersistentOStream & os) const {
os << decayName_ << pdtName_ << reDirect_
<< userDecays_ << checkConv_ << convID_ << p8Data_;
}
void EvtGenInterface::persistentInput(PersistentIStream & is, int) {
is >> decayName_ >> pdtName_ >> reDirect_
>> userDecays_ >> checkConv_ >> convID_ >> p8Data_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<EvtGenInterface,Interfaced>
describeHerwigEvtGenInterface("Herwig::EvtGenInterface",
"HwEvtGenInterface.so");
void EvtGenInterface::Init() {
static ClassDocumentation<EvtGenInterface> documentation
("The EvtGenInterface class is the main class for the use of the EvtGen "
"decay package with Herwig");
static Parameter<EvtGenInterface,string> interfaceDecay_File
("Decay_File",
"The name of the file for the EvtGen decays.",
&EvtGenInterface::decayName_, prefix+"/share/DECAY_2010.DEC",
false, false);
static Parameter<EvtGenInterface,string> interfacePDT_File
("PDTFile",
"The name of the file for the EvtGen particle data.",
&EvtGenInterface::pdtName_, prefix+"/share/evt.pdl",
false, false);
static Switch<EvtGenInterface,bool> interfaceRedirect
("Redirect",
"By default cerr and cout are redirected when EvtGen is running to"
" allow us to catch errors, due to EvtGen's poor internal error "
"handling. This can be a problem for debugging and so can be switched off.",
&EvtGenInterface::reDirect_, true, false, false);
static SwitchOption interfaceRedirectYes
(interfaceRedirect,
"Yes",
"Redirect the output",
true);
static SwitchOption interfaceRedirectNo
(interfaceRedirect,
"No",
"Don't redirect the output",
false);
static Switch<EvtGenInterface,bool> interfaceCheckConversion
("CheckConversion",
"Check the conversion of particles to and from EvtGen",
&EvtGenInterface::checkConv_, false, false, false);
static SwitchOption interfaceCheckConversionfalse
(interfaceCheckConversion,
"No",
"Don't check the conversion",
false);
static SwitchOption interfaceCheckConversionCheck
(interfaceCheckConversion,
"Yes",
"Check the conversion",
true);
static ParVector<EvtGenInterface,long> interfaceOutputModes
("OutputModes",
"Particles for which to output the EvtGen decay modes"
" so they can be read into Herwig",
&EvtGenInterface::convID_, -1, long(0), 0, 0,
false, false, Interface::nolimits);
static ParVector<EvtGenInterface,string> interfaceUserDecays
("UserDecays",
"List of user decay files to be loaded",
&EvtGenInterface::userDecays_, -1, "", "", "",
false, false, Interface::nolimits);
static Parameter<EvtGenInterface,string> interfacePythia8Data
("Pythia8Data",
"Location of the Pythia8 data directory",
&EvtGenInterface::p8Data_, p8data,
false, false);
}
void EvtGenInterface::doinitrun() {
Interfaced::doinitrun();
// redirect cerr and cout if needed
std::streambuf *temp[2]={cout.rdbuf(),cerr.rdbuf()};
if(reDirect_ && ! generator()->useStdOut() ) {
const string f = generator()->filename() + "-EvtGen.log";
logFile_.open(f);
std::streambuf *psbuf = logFile_.rdbuf();
cout.rdbuf(psbuf);
cerr.rdbuf(psbuf);
}
// output the EvtGen initialization info to the log file
cout << "Initializing EvtGen \n";
// set up the random number generator for EvtGen
cout << "Setting EvtGen random number generator"
<< " to the Herwig one.\n";
evtrnd_ = new EvtGenRandom(const_ptr_cast<Ptr<RandomGenerator>::pointer>
(&(UseRandom::current())));
EvtRandom::setRandomEngine(evtrnd_);
// PHOTOS STUFF
EvtAbsRadCorr* radCorrEngine = 0;
std::list<EvtDecayBase*> extraModels;
EvtExternalGenList genList(true,p8Data_,"gamma",true);
radCorrEngine = genList.getPhotosModel();
extraModels = genList.getListOfModels();
// Initialize EvtGen
evtgen_ = new EvtGen(decayName_.c_str(),pdtName_.c_str(),
evtrnd_, radCorrEngine, &extraModels);
// additional user decays
for(unsigned int ix=0;ix<userDecays_.size();++ix)
evtgen_->readUDecay(userDecays_[ix].c_str());
// check the conversion of particles if needed
if(checkConv_) checkConversion();
// convert any particle decay modes which are needed
for(unsigned int ix=0;ix<convID_.size();++ix) {
outputEvtGenDecays(convID_[ix]);
}
// that's the lot
cout << "Finished initialisation of EvtGen \n";
if(reDirect_ && ! generator()->useStdOut() ) {
cout.rdbuf(temp[0]);
cerr.rdbuf(temp[1]);
}
}
void EvtGenInterface::dofinish() {
Interfaced::dofinish();
if(logFile_.is_open())
logFile_.close();
}
ParticleVector EvtGenInterface::decay(const Particle &parent,
bool recursive, const DecayMode & dm) const {
// redirect cout to the log file
ostringstream stemp;
std::streambuf *temp[2]={cout.rdbuf(),cerr.rdbuf()};
if(reDirect_ && ! generator()->useStdOut() ) {
std::streambuf *psbuf[2] ={logFile_.rdbuf(),stemp.rdbuf()};
cout.rdbuf(psbuf[0]);
cerr.rdbuf(psbuf[1]);
}
// generate the decay
ParticleVector output;
EvtId parID(EvtGenID(parent.id()));
try {
EvtDecayBase *decayer = NULL;
// create evtgen particle for the parent
EvtParticle* particle = EvtGenParticle(parent);
EvtParticle* evtParent = NULL;
// special if parent is the same to avoid doing mixing twice
if(parent.parents().size()==1 && abs(parent.parents()[0]->id())==abs(parent.id())) {
evtParent = EvtGenParticle(*parent.parents()[0]);
particle->addDaug(evtParent);
}
// simplest case, evtgen selects mode and recursively decays, use their standard mechanism
if(dm.wildProductMatcher() && recursive) {
evtgen_->generateDecay(particle);
}
// otherwise we're in control
else {
// select the EvtGen decayer to use
if(dm.wildProductMatcher()) {
decayer = EvtDecayTable::getInstance()->getDecayFunc(particle);
}
// otherwise we should pick one
else {
int imode(EvtGenChannel(dm));
decayer = EvtDecayTable::getInstance()->getDecay(parID.getAlias(),imode);
particle->setChannel(imode);
}
// must be a decayer
if(!decayer) throw Exception() << "Could find EvtGen decayer in EvtGen::decay()"
<< Exception::runerror;
// masses of the children
bool massTreeOK(true);
if ( particle->getNDaug() == 0 )
massTreeOK = particle->generateMassTree();
if ( ! massTreeOK ) {
// delete the EvtGen particle
particle->deleteDaughters();
delete particle;
particle = 0;
if(evtParent) {
delete evtParent;
}
- throw Exception() << "EvtGen could not decay " << EvtPDL::name(particle->getId())
- <<" with mass "<< particle->mass()
- <<" to decay channel number "<< particle->getChannel() << "\n"
+ throw Exception() << "EvtGen could not decay " << parent.PDGName()
+ << " with mass " << parent.mass()/GeV
+ << " and decay mode " << dm.tag() << "\n"
<< Exception::eventerror;
}
assert(decayer !=0 );
// perform decay
decayer->makeDecay(particle,recursive);
}
// cast the decayer
EvtDecayAmp *damp = dynamic_cast<EvtDecayAmp*>(decayer);
// translate the decay products
output=decayProducts(particle);
// set spin information if needed
tSpinPtr pspin(getSpinInfo(parent));
// if has spin information translate it
if(damp) {
ParticleVector products;
unsigned int nbeforerad=decayer->getNDaug();
for(unsigned int ix=0;ix<nbeforerad;++ix) products.push_back(output[ix]);
constructVertex(parent,products,damp);
}
// otherwise
else {
pspin->develop();
RhoDMatrix rhotemp(pspin->iSpin());
pspin->DMatrix()=rhotemp;
}
pspin->decay();
if(recursive) {
pspin->developed();
pspin->DMatrix()=ThePEGSpinDensity(particle->getSpinDensityBackward(),
ThePEGID(particle->getId()));
}
// delete the EvtGen particle
particle->deleteDaughters();
delete particle;
if(evtParent) {
delete evtParent;
}
particle = 0;
}
catch ( ... ) {
// change stream back
if(reDirect_ && ! generator()->useStdOut() ) {
cout.rdbuf(temp[0]);
cerr.rdbuf(temp[1]);
}
throw;
}
// change stream back
if(reDirect_ && ! generator()->useStdOut() ) {
cout.rdbuf(temp[0]);
cerr.rdbuf(temp[1]);
string stemp2=stemp.str();
if(stemp2.length()>0)
throw Exception() << "EvtGen report error in EvtGen::decay "
<< "killing event\n"
<< "Error was " << stemp2
<< Exception::eventerror;
}
// return the decay products
return output;
}
EvtParticle * EvtGenInterface::EvtGenParticle(const Particle & part) const {
// convert the momentum
Lorentz5Momentum inmom(part.momentum());
EvtVector4R p4(EvtGenMomentum(inmom));
EvtParticle *evtpart;
// EvtGen ID and spin type
EvtId id = EvtGenID(part.id());
EvtSpinType::spintype thisSpin=EvtPDL::getSpinType(id);
// boost to the rest frame to get the basis states right
PPtr decay(const_ptr_cast<PPtr>(new_ptr(part)));
decay->transform(LorentzRotation(-inmom.boostVector()));
// get spin information so can transfer to EvtGen
tcSpinPtr spin(dynamic_ptr_cast<tcSpinPtr>(part.spinInfo()));
if(spin) spin->decay();
// don't convert neutrinos, aren't decays so waste of time
if ( thisSpin == EvtSpinType::NEUTRINO) {
throw Exception() << "Tried to convert a neutrino to EvtGen in "
<< "EvtGen::EvtParticle. This should not be needed as"
<< "EvtGen does not decay neutrinos"
<< Exception::eventerror;
}
// don't convert photons, aren't decays so waste of time
else if ( thisSpin == EvtSpinType::PHOTON ) {
throw Exception() << "Tried to convert a photon to EvtGen in "
<< "EvtGen::EvtParticle. This should not be needed as"
<< "EvtGen does not decay photons"
<< Exception::eventerror;
}
// scalar particles
else if ( thisSpin == EvtSpinType::SCALAR ) {
// create particle
EvtScalarParticle * myPart = new EvtScalarParticle;
myPart->init(id, p4);
// set rho matrix if needed
tcScalarSpinPtr sp(dynamic_ptr_cast<tcScalarSpinPtr>(spin));
if(sp) {
myPart->setSpinDensityForward(EvtGenSpinDensity(sp->rhoMatrix()));
}
else {
EvtSpinDensity rho;
rho.setDiag(EvtSpinType::getSpinStates(thisSpin));
myPart->setSpinDensityForward(rho);
}
evtpart=myPart;
}
else if ( thisSpin == EvtSpinType::DIRAC ) {
EvtDiracParticle *myPart =new EvtDiracParticle;
// get the spin info
tcFermionSpinPtr sp(dynamic_ptr_cast<tcFermionSpinPtr>(spin));
// has spin info transfer
if(sp) {
vector<EvtDiracSpinor> prod,decay;
// transfer spinors
for(unsigned int ix=0;ix<2;++ix) {
prod .push_back(EvtGenSpinor(sp->getProductionBasisState(ix)));
decay.push_back(EvtGenSpinor(sp->getDecayBasisState (ix)));
}
myPart->init(id, p4,prod[0],prod[1],decay[0],decay[1]);
// set the density matrix
myPart->setSpinDensityForward(EvtGenSpinDensity(sp->rhoMatrix()));
}
// no spin info
else {
myPart->init(id, p4);
EvtSpinDensity rho;
rho.setDiag(EvtSpinType::getSpinStates(thisSpin));
myPart->setSpinDensityForward(rho);
}
evtpart=myPart;
}
// vector particles
else if ( thisSpin == EvtSpinType::VECTOR ) {
EvtVectorParticle *myPart=new EvtVectorParticle;
// get the spin info
tcVectorSpinPtr sp(dynamic_ptr_cast<tcVectorSpinPtr>(spin));
// has spin info transfer
if(sp) {
// transfer polarization vectors
vector<EvtVector4C> eps;
for(unsigned int ix=0;ix<3;++ix) {
eps.push_back(EvtGenPolarization(sp->getDecayBasisState(ix)));
}
myPart->init(id, p4,eps[0],eps[1],eps[2]);
// set spin density matrix
myPart->setSpinDensityForward(EvtGenSpinDensity(sp->rhoMatrix()));
}
// no spin info
else {
myPart->init(id, p4);
EvtSpinDensity rho;
rho.setDiag(EvtSpinType::getSpinStates(thisSpin));
myPart->setSpinDensityForward(rho);
}
evtpart=myPart;
}
// spin 3/2 particles
else if ( thisSpin == EvtSpinType::RARITASCHWINGER ) {
EvtRaritaSchwingerParticle *myPart=new EvtRaritaSchwingerParticle;
// get the spin info
tcRSFermionSpinPtr sp(dynamic_ptr_cast<tcRSFermionSpinPtr>(spin));
// has spin info transfer
if(sp) {
// transfer spinors
vector<EvtRaritaSchwinger> prod,decay;
for(unsigned int ix=0;ix<4;++ix) {
prod .push_back(EvtGenRSSpinor(sp->getProductionBasisState(ix)));
decay.push_back(EvtGenRSSpinor(sp->getDecayBasisState(ix) ));
}
myPart->init(id, p4,
prod[0] ,prod[1] ,prod[2] , prod[3],
decay[0],decay[1],decay[2],decay[3]);
// set spin density matrix
myPart->setSpinDensityForward(EvtGenSpinDensity(sp->rhoMatrix()));
}
// no spin info
else {
myPart->init(id, p4);
EvtSpinDensity rho;
rho.setDiag(EvtSpinType::getSpinStates(thisSpin));
myPart->setSpinDensityForward(rho);
}
evtpart=myPart;
}
// spin-2 particles
else if ( thisSpin == EvtSpinType::TENSOR ) {
EvtTensorParticle *myPart =new EvtTensorParticle;
tcTensorSpinPtr sp(dynamic_ptr_cast<tcTensorSpinPtr>(spin));
// has spin info transfer
if(sp) {
// transfer the polarization tensors
vector<EvtTensor4C> eps;
for(unsigned int ix=0;ix<5;++ix) {
eps.push_back(EvtGenTensor(sp->getDecayBasisState(ix)));
}
myPart->init(id, p4,eps[0],eps[1],eps[2],eps[3],eps[4]);
// set spin density matrix
myPart->setSpinDensityForward(EvtGenSpinDensity(sp->rhoMatrix()));
}
// no spin info
else {
myPart->init(id, p4);
EvtSpinDensity rho;
rho.setDiag(EvtSpinType::getSpinStates(thisSpin));
myPart->setSpinDensityForward(rho);
}
evtpart=myPart;
}
// shouldn't be doing this but here for safety
else if ( thisSpin == EvtSpinType::STRING ) {
EvtStringParticle *myPart;
myPart=new EvtStringParticle;
myPart->init(id, p4);
EvtSpinDensity rho;
rho.setDiag(EvtSpinType::getSpinStates(thisSpin));
myPart->setSpinDensityForward(rho);
evtpart=myPart;
}
// high spin particles
else if ( thisSpin == EvtSpinType::SPIN3 || thisSpin == EvtSpinType::SPIN5HALF ||
thisSpin == EvtSpinType::SPIN4 || thisSpin == EvtSpinType::SPIN7HALF) {
EvtHighSpinParticle *myPart;
myPart=new EvtHighSpinParticle;
myPart->init(id, p4);
EvtSpinDensity rho;
rho.setDiag(EvtSpinType::getSpinStates(thisSpin));
myPart->setSpinDensityForward(rho);
evtpart=myPart;
}
else {
throw Exception() << "Can't convert particle to EvtGen "
<< part << Exception::eventerror;
}
// boost particle back and return the particle
decay->boost(inmom.boostVector());
return evtpart;
}
// convert from ThePEG to EvtGen
EvtId EvtGenInterface::EvtGenID(int id, bool exception) const {
EvtId output;
int absid=abs(id),ispin(absid%10),isgn(id/absid);
// handle the easy cases
if(
//quarks(+excited)
absid<=8||
// leptons(+exicted)
(absid>=11&&absid<=18)||
// SM(+extensions) gauge bosons and higgs
(absid>=21&&absid<=25)||(absid>=32&&absid<=37)||
// 1 1S0, 1 3S1 and 1 3P2 1 3D3 mesons are the same
(absid>100&&absid<600&&ispin%2==1&&ispin<=9)||
// 2 1S0, 2 3S1 are the same
(absid>100100&&absid<100600&&(ispin==1||ispin==3))||
// 1 3d1 goes to 3s in evtgen
(absid>30100&&absid<30600&&ispin==3) ||
// 1 1P1 mesons are the same apart from D_s1
(absid>10100&&absid<10600&&(ispin==3)) ||
// 1 3P1 mesons are the same apart from D_s1
(absid>20100&&absid<20600&&(ispin==3)) ||
// mixed kaons and diffractive states
(absid>=100&&absid<=3000&&ispin==0)) {
output = EvtPDL::evtIdFromStdHep(id);
}
// lowest baryon multiplets and diquarks are almost the same
else if(absid>1000&&absid<6000&&ispin>=1&&ispin<=4) {
output = EvtPDL::evtIdFromStdHep(id);
}
// 1 3p0 same apart from f'0
else if (absid>10100&&absid<10600&&ispin==1) {
if(absid==10221) output = EvtPDL::evtIdFromStdHep(isgn*30221);
else output = EvtPDL::evtIdFromStdHep(id);
}
// excited baryons
else if(((absid>10000&&absid<16000)||(absid>20000&&absid<26000)||
(absid>30000&&absid<36000))&&(ispin==2||ispin==4)) {
output=EvtPDL::evtIdFromStdHep(id);
}
// special for any bottomonium states
else if((absid%1000)/10==55) {
output=EvtPDL::evtIdFromStdHep(id);
}
// special meson codes
else if (absid>9000000) {
// f_0/a_0(980) goes into f_0/a_0(980)
if(absid==9000111||absid==9000211||absid==9010221) {
output=EvtPDL::evtIdFromStdHep(id);
}
// sigma
else if(absid==9000221) {
output=EvtPDL::evtIdFromStdHep(id);
}
// psi(4040)
else if(absid==9000443) {
output=EvtPDL::evtIdFromStdHep(50443);
}
// f_0(1500)
else if(absid==9030221) {
output=EvtPDL::evtIdFromStdHep(9020221);
}
}
// check its O.K.
if(output.getAlias()==-1&&exception) {
throw Exception() << "Can't find the EvtGen Id for particle "
<< getParticleData(id)->PDGName()
<< " with PDG code = "
<< id << " in EvtGen::EvtGenID"
<< Exception::eventerror;
}
return output;
}
ParticleVector EvtGenInterface::decayProducts(EvtParticle *part, bool boost) const {
ParticleVector output,temp;
for(unsigned int ix=0,N=part->getNDaug();ix<N;++ix) {
// get the daughter particle
EvtParticle * daug = part->getDaug(ix);
// may just have been used for mass generation, so check has valid momentum
if(!daug->hasValidP4()) continue;
// get the Herwig ParticleData object
int id=ThePEGID(daug->getId());
tcPDPtr pd=getParticleData(id);
// if easy to convert do it
if(pd) output.push_back(ThePEGParticle(daug,pd));
// special for EvtGen particles like string we don't need to include
else if(id==90) {
// check if needs to be decayed by EvtGen
if(EvtPDL::getStdHep(daug->getId())==92||daug->isDecayed()) {
// add the particles
ParticleVector temp(decayProducts(daug,EvtPDL::getStdHep(daug->getId())!=92));
if(EvtPDL::getStdHep(daug->getId())==92) {
Lorentz5Momentum pstring(ThePEGMomentum(daug->getP4(),daug->mass()));
Boost bv(-pstring.x()/pstring.e(),-pstring.y()/pstring.e(),-pstring.z()/pstring.e());
for(unsigned int ix=0;ix<temp.size();++ix) {
temp[ix]->deepBoost(bv);
}
}
for(unsigned int iy=0;iy<temp.size();++iy) output.push_back(temp[iy]);
}
else if(!daug->isDecayed()) {
EvtDecayBase *decayer = EvtDecayTable::getInstance()->getDecayFunc(daug);
// must be a decayer
if(!decayer) throw Exception() << "Could find EvtGen decayer in "
<< "EvtGenInterface::decayProducts()"
<< Exception::runerror;
// If there are already daughters, then this step is already done!
// figure out the masses
if ( daug->getNDaug() == 0 ) daug->generateMassTree();
// perform decay
decayer->makeDecay(daug,false);
// add the particles
ParticleVector temp(decayProducts(daug));
for(unsigned int iy=0;iy<temp.size();++iy) output.push_back(temp[iy]);
}
}
else {
throw Exception() << "Tried to convert an unknown particle, PDG code = " << id
<< " from EvtGen in EvtGen::decayproducts which is "
<< " unknown to Herwig. Killing event."
<< Exception::eventerror;
}
}
// boost to lab
if(output.size()>0) {
if(boost) {
Boost bv=ThePEGMomentum(part->getP4(),part->mass()).boostVector();
for(unsigned int ix=0; ix<output.size(); ++ix) output[ix]->deepBoost(bv);
}
}
return output;
}
void EvtGenInterface::ThePEGSpin(PPtr peg,EvtParticle *evt) const {
// if no corresponding ThePEG spin type return
if(evt->getSpinType()==EvtSpinType::STRING||
evt->getSpinType()==EvtSpinType::SPIN3||evt->getSpinType()==EvtSpinType::SPIN4||
evt->getSpinType()==EvtSpinType::SPIN5HALF||
evt->getSpinType()==EvtSpinType::SPIN7HALF) return;
// now deal with the other cases
// scalars
unsigned int ix;
SpinPtr spin;
if(evt->getSpinType()==EvtSpinType::SCALAR) {
ScalarSpinPtr sca(new_ptr(ScalarSpinInfo(peg->momentum(),true)));
spin=sca;
}
// massless spin 1/2
else if(evt->getSpinType()==EvtSpinType::NEUTRINO) {
FermionSpinPtr fer(new_ptr(FermionSpinInfo(peg->momentum(),true)));
spin=fer;
ix=peg->id()<0;
fer->setBasisState(ix,ThePEGSpinor(evt->spParentNeutrino()));
ix=peg->id()>0;
fer->setBasisState(ix,LorentzSpinor<SqrtEnergy>());
}
// massive spin-1/2
else if(evt->getSpinType()==EvtSpinType::DIRAC) {
FermionSpinPtr fer(new_ptr(FermionSpinInfo(peg->momentum(),true)));
spin=fer;
for(ix=0;ix<2;++ix) {
fer->setBasisState(ix,ThePEGSpinor(evt->spParent(ix)));
}
}
// massless vectors
else if(evt->getSpinType()==EvtSpinType::PHOTON) {
VectorSpinPtr vec(new_ptr(VectorSpinInfo(peg->momentum(),true)));
spin=vec;
for(ix=0;ix<1;++ix) {
vec->setBasisState(2*ix,ThePEGPolarization(evt->epsParentPhoton(ix)));}
vec->setBasisState(1,LorentzVector<Complex>());
}
// massive vectors
else if(evt->getSpinType()==EvtSpinType::VECTOR) {
VectorSpinPtr vec(new_ptr(VectorSpinInfo(peg->momentum(),true)));
spin=vec;
for(ix=0;ix<3;++ix) {
vec->setBasisState(ix,ThePEGPolarization(evt->epsParent(ix)));
}
}
// massive spin 3/2
else if(evt->getSpinType()==EvtSpinType::RARITASCHWINGER) {
RSFermionSpinPtr rs(new_ptr(RSFermionSpinInfo(peg->momentum(),true)));
spin=rs;
for(ix=0;ix<4;++ix) {
rs->setBasisState(ix,ThePEGRSSpinor(evt->spRSParent(ix)));}
}
// tensors
else if(evt->getSpinType()==EvtSpinType::TENSOR) {
TensorSpinPtr ten(new_ptr(TensorSpinInfo(peg->momentum(),true)));
spin=ten;
for(ix=0;ix<5;++ix) {
ten->setBasisState(ix,ThePEGTensor(evt->epsTensorParent(ix)));
}
}
else {
throw Exception() << "Unknown EvtGen spin type in EvtGen::ThePEGSpin() "
<< Exception::runerror;
}
// set the spininfo
peg->spinInfo(spin);
// final set up if the particle has decayed
if(evt->getSpinDensityForward().getDim()!=0) {
spin->rhoMatrix()=ThePEGSpinDensity(evt->getSpinDensityForward(),peg->id());
}
if(evt->isDecayed()) {
spin->decayed(true);
spin->develop();
if(evt->getSpinDensityBackward().getDim()!=0) {
spin->DMatrix()=ThePEGSpinDensity(evt->getSpinDensityBackward(),peg->id());
}
}
}
// convert from EvtGen to ThePEG
int EvtGenInterface::ThePEGID(EvtId eid,bool exception) const {
int output(0);
int id(EvtPDL::getStdHep(eid)),absid(abs(id)),ispin(absid%10);
// handle the easy cases
// special particles like string which we delete and include decay products
if(absid==92||absid==41||absid==42||absid==43||absid==44||
absid==30343||absid==30353||
absid==30363||absid==30373||absid==30383) {
output=90;
}
//quarks(+excited)
else if(absid<=8||
// leptons(+excited)
(absid>=11&&absid<=18)||
// SM gauge bosons and higgs
(absid>=21&&absid<=25)||(absid>=32&&absid<=37)||
// 1 1S0, 1 3S1 and 1 3P2 mesons are the same
(absid>100&&absid<600&&(ispin%2==1&&ispin<9))||
// 2 1S0 and 2 3S1 mesons are the same
(absid>100100&&absid<100600&&(ispin==1||ispin==3))||
// 1 3p0 are the same
(absid>10100&&absid<10600&&ispin==1) ||
// 3d1 are the same
(absid>30100&&absid<30600&&ispin==3) ||
// 1 1P1 mesons are the same
(absid>10100&&absid<10600&&(ispin==3)) ||
// 1 3P1 mesons are the same
(absid>20100&&absid<20600&&(ispin==3)) ||
// lowest baryon multiplets and diquarks
(absid>1000&&absid<6000&&ispin>=1&&ispin<=4)||
// mixed kaons and diffractive states
(absid>=100&&absid<=3000&&ispin==0)) {
output=id;
}
// 1 3P0 special for f'0
else if(absid==30221)
output = 10221;
// special for the virtual W (we don't distinguish so return W)
else if(absid==89) return id/absid*24;
// excited baryons
else if(((absid>10000&&absid<16000)||(absid>20000&&absid<26000)||
(absid>30000&&absid<36000))&&(ispin==2||ispin==4)) {
output=id;
}
// bottomium
else if((absid%1000)/10==55) {
output = id;
}
// special mesons
else if(absid>9000000) {
// f_0/a_0(980) goes into f_0/a_0(980)
if(absid==9000111||absid==9000211||absid==9010221) {
output=id;
}
// sigma
else if(absid==9000221) {
output=id;
}
// psi(4040)
else if(absid==9000443) {
output=id;
}
// f_0(1500)
else if(absid==9020221) {
output=9030221;
}
}
// check its O.K.
if(output==0&&exception) {
throw Exception() << "Can't find the ThePEG id for particle "
<< EvtPDL::name(eid)
<< " with PDG code = "
<< id << " in EvtGen::ThePEGID"
<< Exception::eventerror;
}
return output;
}
RhoDMatrix EvtGenInterface::ThePEGSpinDensity(const EvtSpinDensity & rho, int id) const {
RhoDMatrix output;
unsigned int ix,iy;
// special for neutrinos
if(abs(id)%2==0&&abs(id)>=12&&abs(id)<=16) {
output = RhoDMatrix(PDT::Spin1Half, false);
if(id>0) output(0,0)=ThePEGComplex(rho.get(0,0));
else output(1,1)=ThePEGComplex(rho.get(0,0));
}
// special for photons
else if(id==ParticleID::gamma) {
output = RhoDMatrix(PDT::Spin1, false);
for(ix=0;ix<2;++ix) {
for(iy=0;iy<2;++iy) output(2*ix,2*iy)=ThePEGComplex(rho.get(ix,iy));
}
}
// normal behaviour
else {
unsigned int ndim(abs(rho.getDim()));
if(ndim!=0) {
output = RhoDMatrix(PDT::Spin(ndim));
for(ix=0;ix<ndim;++ix) {
for(iy=0;iy<ndim;++iy) output(ix,iy)=ThePEGComplex(rho.get(ix,iy));
}
}
else if(ndim==0) {
output = RhoDMatrix(PDT::Spin0);
}
}
return output;
}
void EvtGenInterface::checkConversion() const {
// check the translation of particles from ThePEG to EvtGen.
ParticleMap::const_iterator pit = generator()->particles().begin();
ParticleMap::const_iterator pend = generator()->particles().end();
cout << "Testing conversion of particles from ThePEG to EvtGen\n";
EvtId etemp;
for(;pit!=pend;++pit) {
cout << pit->first << " ";
etemp=EvtGenID(pit->first,false);
Energy mass = pit->second->mass();
Energy width = pit->second->width();
if(etemp.getAlias()>=0) {
cout << pit->second->PDGName() << "\t becomes "
<< EvtPDL::name(etemp) << "\t "
<< EvtPDL::getStdHep(etemp);
if(ThePEGID(etemp,false)-pit->first!=0) {
cout << " and converting back to ThePEG fails";
}
double mass2 = EvtPDL::getMeanMass(etemp);
double width2 = EvtPDL::getWidth(etemp);
if(mass!=ZERO) {
double delta = (mass-mass2*GeV)/mass;
if(abs(delta)>1e-6)
cout << " Mass Difference " << mass/GeV-mass2;
}
if(width>ZERO) {
double delta = (width-width2*GeV)/width;
if(abs(delta)>1e-6)
cout << " Width Difference " << width/GeV-width2;
}
cout << "\n";
}
else {
cout << pit->second->PDGName()
<< " has no match in EvtGen \n";
}
}
// test the conversion the other way
cout << "Testing conversion of particles from EvtGen to ThePEG\n";
int idtemp;
tcPDPtr ptemp;
for(unsigned int ix=0;ix<EvtPDL::entries();++ix) {
cout << EvtPDL::getStdHep(EvtPDL::getEntry(ix)) << " "
<< EvtPDL::name(EvtPDL::getEntry(ix));
idtemp=ThePEGID(EvtPDL::getEntry(ix),false);
ptemp=getParticleData(idtemp);
if(ptemp) {
cout << " becomes " << ptemp->PDGName() << " "
<< ptemp->id();
if(EvtGenID(ptemp->id(),false)!=EvtPDL::getEntry(ix)) {
cout << " and converting back to EvtGEN fails ";
}
cout << "\n";
}
else {
cout << " has no match in ThePEG \n";
}
}
}
void EvtGenInterface::outputEvtGenDecays(long parentid) const {
// output the decay modes from EvtGen so we can read them in
EvtId parent(EvtGenID(parentid));
// get evtids for children
cout << "Outputting decays for "
<< getParticleData(parentid)->PDGName() << "\n";
for(int ix=0;ix<EvtDecayTable::getInstance()->getNMode(parent.getAlias());++ix) {
EvtDecayBase* decayer=EvtDecayTable::getInstance()->getDecay(parent.getAlias(),ix);
vector<long> pegid;
for(int iy=0;iy<decayer->getNDaug();++iy) {
pegid.push_back(ThePEGID(decayer->getDaug(iy),false));
}
for(unsigned int iy=pegid.size();iy<7;++iy) pegid.push_back(0);
double br=decayer->getBranchingFraction();
cout
<< "insert into decay_modes (incomingID,BR,decayon,star,outgoingID1,"
<< "outgoingID2,outgoingID3,outgoingID4,outgoingID5,outgoingID6,outgoingID7,"
<< "description,decayer) values (" << parentid << "," << br << ",'on','*',";
for(int iy=0;iy<7;++iy) {
cout << pegid[iy] << ",";
}
cout << "'Decay of %name% with branching "
<< "ratio taken from EvtGen.',3);\n";
}
}
int EvtGenInterface::EvtGenChannel(const DecayMode & dm) const {
// get evtid for parent
EvtId parent(EvtGenID(dm.parent()->id()));
// get evtids for children
EvtId daugs[20];
unsigned int ndaug(0);
ParticleMSet::const_iterator pit = dm.products().begin();
ParticleMSet::const_iterator pend = dm.products().end();
EvtId etemp;
for( ;pit!=pend&&ndaug<20;++pit) {
etemp=EvtGenID((**pit).id());
daugs[ndaug]=etemp;
ndaug++;
}
if(ndaug>=20) throw Exception() << "Too many decay products "
<< "in EvtGen::EvtGenChannel"
<< Exception::eventerror;
// find the channel
int output=EvtDecayTable::getInstance()->inChannelList(parent,ndaug,daugs);
if(output<0) {
string dmode;
dmode = "decay of " + dm.parent()->PDGName() + " -> ";
pit = dm.products().begin();
pend = dm.products().end();
for( ;pit!=pend&&ndaug<20;++pit) dmode += (**pit).PDGName()+" ";
throw Exception() << "Can't find EVtGen decay mode in EvtGenChannel for "
<< dmode << " in EvtGen::EvtGenChannel"
<< Exception::runerror;
}
return output;
}
// translate the matrix element to our form
void EvtGenInterface::constructVertex(const Particle & parent,
ParticleVector products,
EvtDecayAmp* damp) const {
unsigned int ix,iy;
vector <PDT::Spin> outspin;
for(ix=0;ix<products.size();++ix) {
outspin.push_back(products[ix]->dataPtr()->iSpin());
}
vector<int> constants(products.size()+2,0);
unsigned int nstate(1),idtemp;
for(ix=outspin.size();ix>0;--ix) {
idtemp=abs(products[ix-1]->id());
if(idtemp==ParticleID::gamma) {
nstate*=2;
constants[ix]=nstate;
}
else if(idtemp%2==0&&idtemp>=12&&idtemp<=16) {
constants[ix]=nstate;
}
else {
nstate*=outspin[ix-1];
constants[ix]=nstate;
}
}
PDT::Spin inspin(parent.dataPtr()->iSpin());
nstate*=inspin;
constants[0]=nstate;
constants[outspin.size()+1]=1;
int eind[10]={0,0,0,0,0,0,0,0,0,0};
unsigned int iloc;
vector<unsigned int> hind(outspin.size()+1,0);
DecayMEPtr newME = new_ptr(GeneralDecayMatrixElement(inspin,outspin));
for(ix=0;ix<nstate;++ix) {
iloc=0;
hind[0]=ix/constants[1];
if(inspin!=PDT::Spin0) {
eind[iloc]=hind[0];
++iloc;
}
for(iy=0;iy<outspin.size();++iy) {
if(outspin[iy]==PDT::Spin0) {
hind[iy+1]=0;
}
else if(products[iy]->id()==ParticleID::gamma) {
hind[iy+1]=2*(ix%constants[iy+1])/constants[iy+2];
eind[iloc]=hind[iy+1]/2;
++iloc;
}
else if(constants[iy+1]==1) {
hind[iy+1]=products[iy]->id()<0;
}
else {
hind[iy+1]=(ix%constants[iy+1])/constants[iy+2];
eind[iloc]=hind[iy+1];++iloc;
}
}
if(iloc==0) eind[0]=0;
(*newME)(hind)=ThePEGComplex(damp->amplitude().getAmp(eind));
}
// create the decay vertex
VertexPtr vertex(new_ptr(DecayVertex()));
DVertexPtr Dvertex(dynamic_ptr_cast<DVertexPtr>(vertex));
// set the incoming particle for the decay vertex
dynamic_ptr_cast<tcSpinPtr>(parent.spinInfo())->decayVertex(vertex);
for(ix=0;ix<products.size();++ix) {
dynamic_ptr_cast<tcSpinPtr>(products[ix]->spinInfo())
->productionVertex(vertex);
}
// set the matrix element
Dvertex->ME(newME);
}
diff --git a/Decay/EvtGen/EvtGenInterface.h b/Decay/EvtGen/EvtGenInterface.h
--- a/Decay/EvtGen/EvtGenInterface.h
+++ b/Decay/EvtGen/EvtGenInterface.h
@@ -1,486 +1,478 @@
// -*- C++ -*-
#ifndef Herwig_EvtGenInterface_H
#define Herwig_EvtGenInterface_H
//
// This is the declaration of the EvtGenInterface class.
//
#include "EvtGenInterface.fh"
#include "ThePEG/Interface/Interfaced.h"
#include "ThePEG/Vectors/Lorentz5Vector.h"
#include "ThePEG/Helicity/ScalarSpinInfo.h"
#include "ThePEG/Helicity/FermionSpinInfo.h"
#include "ThePEG/Helicity/VectorSpinInfo.h"
#include "ThePEG/Helicity/RSFermionSpinInfo.h"
#include "ThePEG/Helicity/TensorSpinInfo.h"
#include "ThePEG/EventRecord/Particle.h"
#include "EvtGenRandom.h"
#include "EvtGen/EvtGen.hh"
#include "EvtGenBase/EvtParticle.hh"
#include "EvtGenBase/EvtSpinDensity.hh"
#include "EvtGenBase/EvtVector4R.hh"
#include "EvtGenBase/EvtVector4C.hh"
#include "EvtGenBase/EvtTensor4C.hh"
#include "EvtGenBase/EvtDiracSpinor.hh"
#include "EvtGenBase/EvtRaritaSchwinger.hh"
#include "EvtGenBase/EvtDecayAmp.hh"
namespace Herwig {
using namespace ThePEG;
/**
* The EvtGenInterface class is the main class for the use of the EvtGen decay
* package with Herwig.
*
* @see \ref EvtGenInterfaceInterfaces "The interfaces"
* defined for EvtGenInterface.
*/
class EvtGenInterface: public Interfaced {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
EvtGenInterface();
/**
* The copy constructor (explicit as cannot copy streams)
*/
EvtGenInterface(const EvtGenInterface &);
- /**
- * The destructor.
- */
- virtual ~EvtGenInterface();
- //@}
-
public:
/**
* Use EvtGen to perform a decay
* @param parent The decaying particle
* @param dm The decaymode
* @return The decay products
*/
ParticleVector decay(const Particle &parent,
bool recursive, const DecayMode & dm) 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 Functions to convert between EvtGen and Herwig classes */
//@{
/**
* Convert a particle to an EvtGen particle.
* @param part The particle to be converted.
*/
EvtParticle *EvtGenParticle(const Particle & part) const;
/**
* Return the decay products of an EvtGen particle in as ThePEG particles
* @param evtpart The EvtGen particle
*/
ParticleVector decayProducts(EvtParticle* evtpart, bool boost=true) const;
/**
* Convert a Lorentz5Momentum to a real EvtGen 4-vector
* @param mom The momentum to be converted
*/
EvtVector4R EvtGenMomentum(const Lorentz5Momentum & mom) const {
return EvtVector4R(mom.t()/GeV,mom.x()/GeV,mom.y()/GeV,mom.z()/GeV);
}
/**
* Convert a PDG code from ThePEG into an EvtGen particle id
* @param id The PDG code
* @param exception Whether or not to throw an Exception if fails
*/
EvtId EvtGenID(int id,bool exception=true) const;
/**
* Convert a LorentzSpinor to an EvtGen one. The spinor is converted to the
* EvtGen Dirac representation/
* @param sp The LorentzSpinor
*/
EvtDiracSpinor EvtGenSpinor(const LorentzSpinor<SqrtEnergy> & sp) const {
InvSqrtEnergy norm(sqrt(0.5)/sqrt(GeV));
EvtDiracSpinor output;
output.set(EvtGenComplex(-norm*( sp.s1()+sp.s3())),
EvtGenComplex(-norm*( sp.s2()+sp.s4())),
EvtGenComplex(-norm*(-sp.s1()+sp.s3())),
EvtGenComplex(-norm*(-sp.s2()+sp.s4())));
return output;
}
/**
* Convert a LorentzPolarizationVector to a complex EvtGen 4-vector
* @param eps The polarization vector to be converted
*/
EvtVector4C EvtGenPolarization(const LorentzPolarizationVector & eps) const {
return EvtVector4C(EvtGenComplex(eps.t()),EvtGenComplex(eps.x()),
EvtGenComplex(eps.y()),EvtGenComplex(eps.z()));
}
/**
* Convert our Rarita-Schwinger spinor to the EvtGen one
* @param sp Our RS Spinor
*/
EvtRaritaSchwinger EvtGenRSSpinor(const LorentzRSSpinor<SqrtEnergy> & sp) const {
InvSqrtEnergy norm(sqrt(0.5)/sqrt(GeV));
complex<double> out[4][4];
for(unsigned int ix=0;ix<4;++ix) {
out[ix][0] = -Complex(norm*( sp(ix,0)+sp(ix,2)));
out[ix][1] = -Complex(norm*( sp(ix,1)+sp(ix,3)));
out[ix][2] = -Complex(norm*(-sp(ix,0)+sp(ix,2)));
out[ix][3] = -Complex(norm*(-sp(ix,1)+sp(ix,3)));
}
EvtRaritaSchwinger output;
unsigned int ix,iy;
// remember we have vec,spin and evtgen spin,vec
for(ix=0;ix<4;++ix) {
for(iy=0;iy<4;++iy) output.set(ix,iy,EvtGenComplex(out[iy][ix]));
}
return output;
}
/**
* Convert our tensor to the EvtGen one.
* @param ten Our tensor
*/
EvtTensor4C EvtGenTensor(const LorentzTensor<double> & ten) const {
EvtTensor4C output;
unsigned int ix,iy;
for(ix=0;ix<4;++ix){
for(iy=0;iy<4;++iy) output.set(ix,iy,EvtGenComplex(ten(ix,iy)));
}
return output;
}
/**
* Convert a spin density matrix to an EvtGen spin density matrix.
* @param rho The spin density matrix to be converted.
*/
EvtSpinDensity EvtGenSpinDensity(const RhoDMatrix & rho) const {
EvtSpinDensity rhoout;
unsigned int ix,iy,ispin(rho.iSpin());
rhoout.setDim(ispin);
for(ix=0;ix<ispin;++ix) {
for(iy=0;iy<ispin;++iy)
rhoout.set(ix,iy,EvtGenComplex(rho(ix,iy)));
}
return rhoout;
}
/**
* Convert from our complex to the EvtGen one
*/
EvtComplex EvtGenComplex(Complex c) const {
return EvtComplex(c.real(),c.imag());
}
//@}
/**
* Functions to convert between EvtGen and Herwig classes
*/
//@{
/**
* Convert a particle from an EvtGen one to ThePEG one.
* @param part The EvtGen particle.
* @param pd Pointer to the particle data object of ThePEG for the particle.
* @param spin Convert the spin information as well
*/
PPtr ThePEGParticle(EvtParticle *part, tcPDPtr pd,bool spin=true) const {
PPtr output(new_ptr(Particle(pd)));
output->set5Momentum(ThePEGMomentum(part->getP4(),part->mass()));
if(spin) ThePEGSpin(output,part);
// make the daughters
ParticleVector daug(decayProducts(part,spin));
for(unsigned int ix=0;ix<daug.size();++ix) output->addChild(daug[ix]);
return output;
}
/**
* Set the SpinInfo for a ThePEG particle using an EvtGen particle
* @param pegpart ThePEG particle.
* @param evtpart The EvtGen particle.
*/
void ThePEGSpin(PPtr pegpart,EvtParticle *evtpart) const;
/**
* Convert an EvtGen EvtId to a PDG code in our conventions
* @param id The EvtGen ID.
* @param exception Whether or not to throw an Exception if fails
*/
int ThePEGID(EvtId id,bool exception=true) const;
/**
* Convert from EvtGen momentum to Lorentz5Momentum
* @param mom The EvtGen 4-momentum
* @param mass The mass
*/
Lorentz5Momentum ThePEGMomentum(const EvtVector4R & mom,double mass) const {
return Lorentz5Momentum(mom.get(1)*GeV,mom.get(2)*GeV,
mom.get(3)*GeV,mom.get(0)*GeV,mass*GeV);
}
/**
* Convert from EvtGen complex to ours
*/
Complex ThePEGComplex(EvtComplex c) const {
return Complex(real(c),imag(c));
}
/**
* Convert a spin density to a ThePEG one from an EvtGen one
* @param rho The spin density matrix to be converted
* @param id The PDG code of the particle to get special cases right.
*/
RhoDMatrix ThePEGSpinDensity(const EvtSpinDensity & rho, int id) const;
/**
* Convert an EvtDiracSpinor a LorentzSpinor. This spinor is converted to
* the default Dirac matrix representation used by ThePEG.
* @param sp The EvtDiracSpinor
*/
LorentzSpinor<SqrtEnergy> ThePEGSpinor(const EvtDiracSpinor & sp) const {
SqrtEnergy norm(sqrt(0.5)*sqrt(GeV));
vector<complex<SqrtEnergy> > evtSpin(4);
for(unsigned int ix=0;ix<4;++ix) evtSpin[ix] = -norm*ThePEGComplex(sp.get_spinor(ix));
return LorentzSpinor<SqrtEnergy>(evtSpin[0]-evtSpin[2],evtSpin[1]-evtSpin[3],
evtSpin[0]+evtSpin[2],evtSpin[1]+evtSpin[3]);
}
/**
* Convert an EvtGen complex 4-vector to a LorentzPolarizationVector
* @param eps The complex 4-vector to be converted.
*/
LorentzPolarizationVector ThePEGPolarization(const EvtVector4C & eps) const {
return LorentzPolarizationVector(conj(ThePEGComplex(eps.get(1))),
conj(ThePEGComplex(eps.get(2))),
conj(ThePEGComplex(eps.get(3))),
conj(ThePEGComplex(eps.get(0))));
}
/**
* Convert an EvtGen Rarita-Schwinger spinor to ours
* @param sp The EvtGen RS spinor.
*/
LorentzRSSpinor<SqrtEnergy> ThePEGRSSpinor(const EvtRaritaSchwinger & sp) const {
complex<SqrtEnergy> evtSpin[4][4];
SqrtEnergy norm(sqrt(0.5)*sqrt(GeV));
// normalisation and swap vec,spin order
for(unsigned int ix=0;ix<4;++ix) {
for(unsigned int iy=0;iy<4;++iy) evtSpin[ix][iy]=-norm*ThePEGComplex(sp.get(iy,ix));
}
LorentzRSSpinor<SqrtEnergy> output;
for(unsigned int ix=0;ix<4;++ix) {
output(ix,0) = evtSpin[ix][0] - evtSpin[ix][2];
output(ix,1) = evtSpin[ix][1] - evtSpin[ix][3];
output(ix,2) = evtSpin[ix][0] + evtSpin[ix][2];
output(ix,3) = evtSpin[ix][1] + evtSpin[ix][3];
}
// output.changeRep(Helicity::defaultDRep);
return output;
}
/**
* Convert an EvtGen tensor to ThePEG
* @param ten The EvtGen tensor
*/
LorentzTensor<double> ThePEGTensor(const EvtTensor4C & ten) const {
LorentzTensor<double> output;
unsigned int ix,iy;
for(ix=0;ix<4;++ix) {
for(iy=0;iy<4;++iy)output(ix,iy)=conj(ThePEGComplex(ten.get(ix,iy)));
}
return output;
}
//@}
/**
* Check the conversion of particles between Herwig and EvtGen
*/
void checkConversion() const;
/**
* Output the EvtGen decay modes for a given particle
* @param id The PDG code of the particle to output
*/
void outputEvtGenDecays(long id) const;
/**
* Find the location in the EvtGen list of decay channels for
* a given decay mode.
*/
int EvtGenChannel(const DecayMode &dm) const;
/**
* Check the particle has SpinInfo and if not create it
* @param part The particle
*/
tSpinPtr getSpinInfo(const Particle &part) const {
// return spin info if exists
if(part.spinInfo()) {
return dynamic_ptr_cast<tSpinPtr>(const_ptr_cast<tPPtr>(&part)->spinInfo());
}
// otherwise make it
tPPtr ptemp(const_ptr_cast<tPPtr>(&part));
PDT::Spin spin(part.dataPtr()->iSpin());
SpinPtr pspin;
if(spin==PDT::Spin0) pspin=new_ptr(ScalarSpinInfo(part.momentum(),true));
else if(spin==PDT::Spin1Half) pspin=new_ptr(FermionSpinInfo(part.momentum(),true));
else if(spin==PDT::Spin1) pspin=new_ptr(VectorSpinInfo(part.momentum(),true));
else if(spin==PDT::Spin3Half) pspin=new_ptr(RSFermionSpinInfo(part.momentum(),true));
else if(spin==PDT::Spin2) pspin=new_ptr(TensorSpinInfo(part.momentum(),true));
else throw Exception() << "Can't create spinInfo for decaying particle in "
<< "EvtGen::checkSpinInfo for spin " << spin << "particle "
<< Exception::eventerror;
ptemp->spinInfo(pspin);
return pspin;
}
/**
* Construct the DecayVertex for Herwig using the information from
* EvtGen
* @param parent The decaying particle
* @param products The outgoing particles
* @param damp Pointer to the EvtGen decayer
*/
void constructVertex(const Particle & parent,ParticleVector products,
EvtDecayAmp* damp) const;
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. 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 assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
EvtGenInterface & operator=(const EvtGenInterface &) = delete;
private:
/**
* Names of the various EvtGen parameter files
*/
//@{
/**
* The name of the file containing the decays
*/
string decayName_;
/**
* The name of the file containing the particle data
*/
string pdtName_;
/**
* Names of addition user specified decays
*/
vector<string> userDecays_;
//@}
/**
* Whether or not to redirect cout and cerr when EvtGen is running
*/
bool reDirect_;
/**
* Check the conversion of the particles
*/
bool checkConv_;
/**
* Particles for which to output the EvtGen decays
*/
vector<long> convID_;
/**
* Location of the PYTHIA8 data directory
*/
string p8Data_;
private:
/**
* Pointer to the random number generator for EvtGen
*/
EvtRandomEngine * evtrnd_;
/**
* Main EvtGen object
*/
EvtGen * evtgen_;
/**
* File to output the log info to
*/
mutable ofstream logFile_;
};
}
#endif /* Herwig_EvtGenInterface_H */
diff --git a/Decay/General/VectorCurrentDecayer.cc b/Decay/General/VectorCurrentDecayer.cc
--- a/Decay/General/VectorCurrentDecayer.cc
+++ b/Decay/General/VectorCurrentDecayer.cc
@@ -1,273 +1,272 @@
// -*- C++ -*-
//
// VectorCurrentDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 VectorCurrentDecayer class.
//
#include "VectorCurrentDecayer.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ParVector.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/Decay/GeneralDecayMatrixElement.h"
#include "Herwig/Models/General/BSMModel.h"
using namespace Herwig;
IBPtr VectorCurrentDecayer::clone() const {
return new_ptr(*this);
}
IBPtr VectorCurrentDecayer::fullclone() const {
return new_ptr(*this);
}
void VectorCurrentDecayer::persistentOutput(PersistentOStream & os) const {
os << inpart_ << currentOut_ << current_ << mode_ << wgtloc_ << wgtmax_ << weights_ << cSMmed_;
}
void VectorCurrentDecayer::persistentInput(PersistentIStream & is, int) {
is >> inpart_ >> currentOut_ >> current_ >> mode_ >> wgtloc_ >> wgtmax_ >> weights_ >> cSMmed_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<VectorCurrentDecayer,DecayIntegrator>
describeHerwigVectorCurrentDecayer("Herwig::VectorCurrentDecayer", "Herwig.so");
void VectorCurrentDecayer::Init() {
static ClassDocumentation<VectorCurrentDecayer> documentation
("The VectorCurrentDecayer class is designed for the decays of low mass vector bosons");
}
void VectorCurrentDecayer::setDecayInfo(PDPtr in, const vector<tPDPtr> & outCurrent, WeakCurrentPtr current) {
inpart_ = in;
currentOut_ = outCurrent;
current_ = current;
// cast the model
Ptr<BSMModel>::ptr model = dynamic_ptr_cast<Ptr<BSMModel>::ptr>(generator()->standardModel());
bool foundU(false),foundD(false),foundS(false);
// find the vertices we need and extract the couplings
for(unsigned int ix = 0; ix < model->numberOfVertices(); ++ix ) {
VertexBasePtr vertex = model->vertex(ix);
if(vertex->getNpoint()!=3) continue;
for(unsigned int iloc = 0;iloc < 3; ++iloc) {
vector<long> ext = vertex->search(iloc, in->id());
if(ext.empty()) continue;
for(unsigned int ioff=0;ioff<ext.size();ioff+=3) {
if(iloc!=2) assert(false);
if(abs(ext[ioff])==1 && abs(ext[ioff+1])==1 && ext[ioff]==-ext[ioff+1]) {
foundD = true;
vertex->setCoupling(sqr(in->mass()),getParticleData(1),getParticleData(-1),in);
cSMmed_[0] = vertex->norm();
}
else if(abs(ext[ioff])==2 && abs(ext[ioff+1])==2 && ext[ioff]==-ext[ioff+1]) {
foundU = true;
vertex->setCoupling(sqr(in->mass()),getParticleData(2),getParticleData(-2),in);
cSMmed_[1] = vertex->norm();
}
else if(abs(ext[ioff])==3 && abs(ext[ioff+1])==3 && ext[ioff]==-ext[ioff+1]) {
foundS = true;
vertex->setCoupling(sqr(in->mass()),getParticleData(3),getParticleData(-3),in);
cSMmed_[2] = vertex->norm();
}
}
}
}
if(!foundD) {
throw InitException() << "Cannot find down quark coupling in VectorCurrentDecayer::doinit()";
}
if(!foundU) {
throw InitException() << "Cannot find up quark coupling in VectorCurrentDecayer::doinit()";
}
if(!foundS) {
throw InitException() << "Cannot find strange quark coupling in VectorCurrentDecayer::doinit()";
}
}
int VectorCurrentDecayer::modeNumber(bool & cc, tcPDPtr parent,
const tPDVector & children) const {
vector<long> id;
id.push_back(parent->id());
for(unsigned int ix=0;ix<children.size();++ix) id.push_back(children[ix]->id());
return modeNumber(cc,id);
}
void VectorCurrentDecayer::doinitrun() {
current_->initrun();
DecayIntegrator::doinitrun();
}
void VectorCurrentDecayer::doinit() {
DecayIntegrator::doinit();
// make sure the current got initialised
current_->init();
// find the mode
for(unsigned int ix=0;ix<current_->numberOfModes();++ix) {
// get the external particles for this mode
int iq(0),ia(0);
tPDVector ptemp = current_->particles(inpart_->iCharge(),ix,iq,ia);
// check this is the right mode
if(ptemp.size()!=currentOut_.size()) continue;
vector<bool> matched(ptemp.size(),false);
bool match = true;
for(unsigned int iy=0;iy<currentOut_.size();++iy) {
bool found = false;
for(unsigned int iz=0;iz<ptemp.size();++iz) {
if(!matched[iz]&&ptemp[iz]==currentOut_[iy]) {
found = true;
matched[iz] = true;
break;
}
}
if(!found) {
match = false;
break;
}
}
if(!match) continue;
tPDVector out = {};
out.insert(std::end(out), std::begin(ptemp), std::end(ptemp));
// create the mode
PhaseSpaceModePtr mode = new_ptr(PhaseSpaceMode(inpart_,out,1.));
PhaseSpaceChannel channel(mode,true);
bool done=current_->createMode(inpart_->iCharge(),tcPDPtr(),FlavourInfo(),
ix,mode,0,-1,channel,inpart_->mass());
if(done) {
// the maximum weight and the channel weights
// the weights for the channel
if(weights_.empty()) {
weights_.resize(mode->channels().size(),1./(mode->channels().size()));
}
mode_ = ix;
// special for the two body modes
if(out.size()==2) {
weights_.clear();
mode=new_ptr(PhaseSpaceMode(inpart_,out,1.));
}
mode->maxWeight(wgtmax_);
mode->setWeights(weights_);
addMode(mode);
}
break;
}
}
int VectorCurrentDecayer::modeNumber(bool & cc, vector<long> id) const {
// incoming particle
long idtemp;
tPDPtr p0=getParticleData(id[0]);
idtemp = p0->CC() ? -id[0] : id[0];
if( id[0] ==inpart_->id()) cc=false;
else if(idtemp==inpart_->id()) cc=true ;
else return -1;
vector<int> idout;
for(vector<long>::iterator it=++id.begin();it!=id.end();++it) {
idout.push_back(*it);
}
unsigned int icurr=current_->decayMode(idout);
if(mode_==icurr) return 0;
else return -1;
}
void VectorCurrentDecayer::
constructSpinInfo(const Particle & part, ParticleVector decay) const {
VectorWaveFunction::constructSpinInfo(vectors_,const_ptr_cast<tPPtr>(&part),
Helicity::incoming,true,false);
weakCurrent()->constructSpinInfo(ParticleVector(decay.begin(),decay.end()));
}
double VectorCurrentDecayer::me2(const int ichan, const Particle & part,
const tPDVector & outgoing,
const vector<Lorentz5Momentum> & momenta,
MEOption meopt) const {
using namespace ThePEG::Helicity;
// polarization vectors for the incoming particle
if(meopt==Initialize) {
VectorWaveFunction::calculateWaveFunctions(vectors_,rho_,
const_ptr_cast<tPPtr>(&part),
incoming,false);
// fix rho if no correlations
fixRho(rho_);
}
// work out the mapping for the hadron vector
int nOut = momenta.size();
vector<unsigned int> constants(nOut+1);
vector<PDT::Spin > iSpin(nOut);
vector<int> hadrons(nOut);
int itemp(1);
int ix(nOut);
do {
--ix;
iSpin[ix] = outgoing[ix]->iSpin();
itemp *= iSpin[ix];
constants[ix] = itemp;
hadrons[ix] = outgoing[ix]->id();
}
while(ix>0);
constants[nOut] = 1;
- Energy2 scale(sqr(part.mass()));
// calculate the hadron current
Energy q = part.mass();
// currents for the different flavour components
vector<LorentzPolarizationVectorE>
hadronI0(current_->current(tcPDPtr(), FlavourInfo(IsoSpin::IZero, IsoSpin::I3Zero,Strangeness::Zero),
mode(),ichan,q,outgoing,momenta,DecayIntegrator::Calculate));
vector<LorentzPolarizationVectorE>
hadronI1(current_->current(tcPDPtr(), FlavourInfo(IsoSpin::IOne, IsoSpin::I3Zero,Strangeness::Zero),
mode(),ichan,q,outgoing,momenta,DecayIntegrator::Calculate));
vector<LorentzPolarizationVectorE>
hadronssbar(current_->current(tcPDPtr(), FlavourInfo(IsoSpin::IZero, IsoSpin::I3Zero,Strangeness::ssbar),
mode(),ichan,q,outgoing,momenta,DecayIntegrator::Calculate));
// compute the matrix element
GeneralDecayMEPtr newME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,iSpin)));
vector<unsigned int> ihel(momenta.size()+1);
unsigned int hI0_size = hadronI0.size();
unsigned int hI1_size = hadronI1.size();
unsigned int hss_size = hadronssbar.size();
unsigned int maxsize = max(max(hadronI0.size(),hadronI1.size()),hss_size);
for(unsigned int hhel=0;hhel<maxsize;++hhel) {
// map the index for the hadrons to a helicity state
for(int ix=nOut;ix>0;--ix) {
ihel[ix]=(hhel%constants[ix-1])/constants[ix];
}
for(ihel[0]=0;ihel[0]<3;++ihel[0]) {
Complex amp = 0.;
// work on coefficients for the I1 and I0 bits
if(hI0_size != 0 )
amp += Complex((cSMmed_[0]+cSMmed_[1])/sqrt(2.)/q*(vectors_[ihel[0]].wave().dot(hadronI0[hhel])));
if(hI1_size !=0)
amp += Complex((cSMmed_[0]-cSMmed_[1])/sqrt(2.)/q*(vectors_[ihel[0]].wave().dot(hadronI1[hhel])));
if(hss_size !=0)
amp += Complex(cSMmed_[2] /q*(vectors_[ihel[0]].wave().dot(hadronssbar[hhel])));
(*newME)(ihel) = amp;
}
}
// store the matrix element
ME(newME);
// return the answer
double output = (ME()->contract(rho_)).real();
return output;
}
Energy VectorCurrentDecayer::partialWidth(tPDPtr part, vector<tPDPtr> out) {
vector<long> id;
id.push_back(part->id());
for(unsigned int ix=0;ix<out.size();++ix) id.push_back(out[ix]->id());
bool cc;
int mode=modeNumber(cc,id);
imode(mode);
return initializePhaseSpaceMode(mode,true,true);
}
diff --git a/Decay/Perturbative/SMWDecayer.cc b/Decay/Perturbative/SMWDecayer.cc
--- a/Decay/Perturbative/SMWDecayer.cc
+++ b/Decay/Perturbative/SMWDecayer.cc
@@ -1,740 +1,740 @@
// -*- C++ -*-
//
// SMWDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 SMWDecayer class.
//
#include "SMWDecayer.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/ParVector.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/DecayMode.h"
#include "Herwig/Decay/DecayVertex.h"
#include "ThePEG/Helicity/VectorSpinInfo.h"
#include "ThePEG/Helicity/FermionSpinInfo.h"
#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
#include "Herwig/Models/StandardModel/StandardModel.h"
#include "Herwig/Shower/RealEmissionProcess.h"
#include "Herwig/Decay/GeneralDecayMatrixElement.h"
#include <numeric>
using namespace Herwig;
using namespace ThePEG::Helicity;
const double SMWDecayer::EPS_=0.00000001;
SMWDecayer::SMWDecayer()
: quarkWeight_(6,0.), leptonWeight_(3,0.), CF_(4./3.),
NLO_(false) {
quarkWeight_[0] = 1.01596;
quarkWeight_[1] = 0.0537308;
quarkWeight_[2] = 0.0538085;
quarkWeight_[3] = 1.01377;
quarkWeight_[4] = 1.45763e-05;
quarkWeight_[5] = 0.0018143;
leptonWeight_[0] = 0.356594;
leptonWeight_[1] = 0.356593;
leptonWeight_[2] = 0.356333;
// intermediates
generateIntermediates(false);
}
void SMWDecayer::doinit() {
PerturbativeDecayer::doinit();
// get the vertices from the Standard Model object
tcHwSMPtr hwsm=dynamic_ptr_cast<tcHwSMPtr>(standardModel());
if(!hwsm) throw InitException() << "Must have Herwig StandardModel object in"
<< "SMWDecayer::doinit()"
<< Exception::runerror;
FFWVertex_ = hwsm->vertexFFW();
FFGVertex_ = hwsm->vertexFFG();
WWWVertex_ = hwsm->vertexWWW();
FFPVertex_ = hwsm->vertexFFP();
// make sure they are initialized
FFGVertex_->init();
FFWVertex_->init();
WWWVertex_->init();
FFPVertex_->init();
// now set up the decay modes
// W modes
tPDPtr Wp = getParticleData(ParticleID::Wplus);
// loop for the quarks
unsigned int iz=0;
for(int ix=1;ix<6;ix+=2) {
for(int iy=2;iy<6;iy+=2) {
// check that the combination of particles is allowed
if(!FFWVertex_->allowed(-ix,iy,ParticleID::Wminus))
throw InitException() << "SMWDecayer::doinit() the W vertex"
<< "cannot handle all the quark modes"
<< Exception::abortnow;
tPDVector out = {getParticleData(-ix),
getParticleData( iy)};
PhaseSpaceModePtr mode = new_ptr(PhaseSpaceMode(Wp,out,quarkWeight_[iz]));
addMode(mode);
++iz;
}
}
// loop for the leptons
for(int ix=11;ix<17;ix+=2) {
tPDVector out = {getParticleData(-ix ),
getParticleData( ix+1)};
PhaseSpaceModePtr mode = new_ptr(PhaseSpaceMode(Wp,out,leptonWeight_[(ix-11)/2]));
addMode(mode);
}
gluon_ = getParticleData(ParticleID::g);
}
int SMWDecayer::modeNumber(bool & cc,tcPDPtr parent,
const tPDVector & children) const {
int imode(-1);
if(children.size()!=2) return imode;
int id0=parent->id();
tPDVector::const_iterator pit = children.begin();
int id1=(**pit).id();
++pit;
int id2=(**pit).id();
if(abs(id0)!=ParticleID::Wplus) return imode;
int idd(0),idu(0);
if(abs(id1)%2==1&&abs(id2)%2==0) {
idd=abs(id1);
idu=abs(id2);
}
else if(abs(id1)%2==0&&abs(id2)%2==1) {
idd=abs(id2);
idu=abs(id1);
}
if(idd==0&&idu==0) {
return imode;
}
else if(idd<=5) {
imode=idd+idu/2-2;
}
else {
imode=(idd-1)/2+1;
}
cc= (id0==ParticleID::Wminus);
return imode;
}
ParticleVector SMWDecayer::decay(const Particle & parent,
const tPDVector & children) const {
// generate the decay
bool cc;
unsigned int imode = modeNumber(cc,parent.dataPtr(),children);
ParticleVector output = generate(false,cc,imode,parent);
if(output[0]->hasColour()) output[0]->antiColourNeighbour(output[1]);
else if(output[1]->hasColour()) output[1]->antiColourNeighbour(output[0]);
return output;
}
void SMWDecayer::persistentOutput(PersistentOStream & os) const {
os << FFWVertex_ << quarkWeight_ << leptonWeight_
<< FFGVertex_ << gluon_ << NLO_
<< WWWVertex_ << FFPVertex_;
}
void SMWDecayer::persistentInput(PersistentIStream & is, int) {
is >> FFWVertex_ >> quarkWeight_ >> leptonWeight_
>> FFGVertex_ >> gluon_ >> NLO_
>> WWWVertex_ >> FFPVertex_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<SMWDecayer,PerturbativeDecayer>
describeHerwigSMWDecayer("Herwig::SMWDecayer", "HwPerturbativeDecay.so");
void SMWDecayer::Init() {
static ClassDocumentation<SMWDecayer> documentation
("The SMWDecayer class is the implementation of the decay"
" of the W boson to the Standard Model fermions.");
static ParVector<SMWDecayer,double> interfaceWquarkMax
("QuarkMax",
"The maximum weight for the decay of the W to quarks",
&SMWDecayer::quarkWeight_,
0, 0, 0, -10000, 10000, false, false, true);
static ParVector<SMWDecayer,double> interfaceWleptonMax
("LeptonMax",
"The maximum weight for the decay of the W to leptons",
&SMWDecayer::leptonWeight_,
0, 0, 0, -10000, 10000, false, false, true);
static Switch<SMWDecayer,bool> interfaceNLO
("NLO",
"Whether to return the LO or NLO result",
&SMWDecayer::NLO_, false, false, false);
static SwitchOption interfaceNLOLO
(interfaceNLO,
"No",
"Leading-order result",
false);
static SwitchOption interfaceNLONLO
(interfaceNLO,
"Yes",
"NLO result",
true);
}
void SMWDecayer::
constructSpinInfo(const Particle & part, ParticleVector decay) const {
int iferm(1),ianti(0);
if(decay[0]->id()>0) swap(iferm,ianti);
VectorWaveFunction::constructSpinInfo(vectors_,const_ptr_cast<tPPtr>(&part),
incoming,true,false);
SpinorBarWaveFunction::
constructSpinInfo(wavebar_,decay[iferm],outgoing,true);
SpinorWaveFunction::
constructSpinInfo(wave_ ,decay[ianti],outgoing,true);
}
// return the matrix element squared
double SMWDecayer::me2(const int,const Particle & part,
const tPDVector & outgoing,
const vector<Lorentz5Momentum> & momenta,
MEOption meopt) const {
if(!ME())
ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
int iferm(1),ianti(0);
if(outgoing[0]->id()>0) swap(iferm,ianti);
if(meopt==Initialize) {
VectorWaveFunction::calculateWaveFunctions(vectors_,rho_,
const_ptr_cast<tPPtr>(&part),
incoming,false);
// fix rho if no correlations
fixRho(rho_);
}
SpinorBarWaveFunction wbar(momenta[iferm],outgoing[iferm],Helicity::outgoing);
SpinorWaveFunction w (momenta[ianti],outgoing[ianti],Helicity::outgoing);
wavebar_.resize(2);
wave_ .resize(2);
for(unsigned int ihel=0;ihel<2;++ihel) {
wbar.reset(ihel);
wavebar_[ihel] = wbar;
w.reset(ihel);
wave_ [ihel] = w;
}
// compute the matrix element
Energy2 scale(sqr(part.mass()));
for(unsigned int ifm=0;ifm<2;++ifm) {
for(unsigned int ia=0;ia<2;++ia) {
for(unsigned int vhel=0;vhel<3;++vhel) {
if(iferm>ianti) (*ME())(vhel,ia,ifm)=
FFWVertex_->evaluate(scale,wave_[ia],wavebar_[ifm],vectors_[vhel]);
else (*ME())(vhel,ifm,ia)=
FFWVertex_->evaluate(scale,wave_[ia],wavebar_[ifm],vectors_[vhel]);
}
}
}
double output=(ME()->contract(rho_)).real()*UnitRemoval::E2/scale;
if(abs(outgoing[0]->id())<=6) output*=3.;
// // leading-order result
if(!NLO_) return output;
// check decay products coloured, otherwise return
if(!outgoing[0]->coloured()) return output;
// inital masses, couplings etc
// W mass
mW_ = part.mass();
// strong coupling
aS_ = SM().alphaS(sqr(mW_));
// reduced mass
double mu1 = outgoing[0]->mass()/mW_;
double mu2 = outgoing[1]->mass()/mW_;
// scale
scale_ = sqr(mW_);
// now for the nlo loop correction
double virt = CF_*aS_/Constants::pi;
// now for the real correction
double realFact=0.;
for(int iemit=0;iemit<2;++iemit) {
double phi = UseRandom::rnd()*Constants::twopi;
// set the emitter and the spectator
double muj = iemit==0 ? mu1 : mu2;
double muk = iemit==0 ? mu2 : mu1;
double muj2 = sqr(muj);
double muk2 = sqr(muk);
// calculate y
double yminus = 0.;
double yplus = 1.-2.*muk*(1.-muk)/(1.-muj2-muk2);
double y = yminus + UseRandom::rnd()*(yplus-yminus);
double v = sqrt(sqr(2.*muk2 + (1.-muj2-muk2)*(1.-y))-4.*muk2)
/(1.-muj2-muk2)/(1.-y);
double zplus = (1.+v)*(1.-muj2-muk2)*y/2./(muj2+(1.-muj2-muk2)*y);
double zminus = (1.-v)*(1.-muj2-muk2)*y/2./(muj2+(1.-muj2-muk2)*y);
double z = zminus + UseRandom::rnd()*(zplus-zminus);
double jac = (1.-y)*(yplus-yminus)*(zplus-zminus);
// calculate x1,x2,x3,xT
double x2 = 1.-y*(1.-muj2-muk2)-muj2+muk2;
double x1 = 1.+muj2-muk2-z*(x2-2.*muk2);
// copy the particle objects over for calculateRealEmission
- tcPDVector outgoing = {part.dataPtr(),outgoing[0],outgoing[1],gluon_};
+ tcPDVector oTemp = {part.dataPtr(),outgoing[0],outgoing[1],gluon_};
vector<Lorentz5Momentum> mom = {part.momentum(),momenta[0],momenta[1]};
realFact += 0.25*jac*sqr(1.-muj2-muk2)/
sqrt((1.-sqr(muj-muk))*(1.-sqr(muj+muk)))/Constants::twopi
- *2.*CF_*aS_*calculateRealEmission(x1, x2, outgoing,mom, phi,
+ *2.*CF_*aS_*calculateRealEmission(x1, x2, oTemp, mom, phi,
muj, muk, iemit, true);
}
// the born + virtual + real
output *= (1. + virt + realFact);
return output;
}
void SMWDecayer::doinitrun() {
PerturbativeDecayer::doinitrun();
if(initialize()) {
for(unsigned int ix=0;ix<numberModes();++ix) {
if(ix<6) quarkWeight_ [ix]=mode(ix)->maxWeight();
else leptonWeight_[ix-6]=mode(ix)->maxWeight();
}
}
}
void SMWDecayer::dataBaseOutput(ofstream & output,
bool header) const {
if(header) output << "update decayers set parameters=\"";
for(unsigned int ix=0;ix<quarkWeight_.size();++ix) {
output << "newdef " << name() << ":QuarkMax " << ix << " "
<< quarkWeight_[ix] << "\n";
}
for(unsigned int ix=0;ix<leptonWeight_.size();++ix) {
output << "newdef " << name() << ":LeptonMax " << ix << " "
<< leptonWeight_[ix] << "\n";
}
// parameters for the PerturbativeDecayer base class
PerturbativeDecayer::dataBaseOutput(output,false);
if(header) output << "\n\" where BINARY ThePEGName=\""
<< fullName() << "\";" << endl;
}
void SMWDecayer::
initializeMECorrection(RealEmissionProcessPtr born, double & initial,
double & final) {
// get the quark and antiquark
ParticleVector qq;
for(unsigned int ix=0;ix<born->bornOutgoing().size();++ix)
qq.push_back(born->bornOutgoing()[ix]);
// ensure quark first
if(qq[0]->id()<0) swap(qq[0],qq[1]);
// centre of mass energy
d_Q_ = (qq[0]->momentum() + qq[1]->momentum()).m();
// quark mass
d_m_ = 0.5*(qq[0]->momentum().m()+qq[1]->momentum().m());
// set the other parameters
setRho(sqr(d_m_/d_Q_));
setKtildeSymm();
// otherwise can do it
initial=1.;
final =1.;
}
bool SMWDecayer::softMatrixElementVeto(PPtr parent,
PPtr progenitor,
const bool & ,
const Energy & highestpT,
const vector<tcPDPtr> & ids,
const double & d_z,
const Energy & d_qt,
const Energy & ) {
// check we should be applying the veto
if(parent->id()!=progenitor->id()||
ids[0]!=ids[1]||
ids[2]->id()!=ParticleID::g) return false;
// calculate pt
Energy2 d_m2 = parent->momentum().m2();
Energy2 pPerp2 = sqr(d_z*d_qt) - d_m2;
if(pPerp2<ZERO) return true;
Energy pPerp = (1.-d_z)*sqrt(pPerp2);
// if not hardest so far don't apply veto
if(pPerp<highestpT) return false;
// calculate the weight
double weight = 0.;
if(parent->id()>0) weight = qWeightX(d_qt, d_z);
else weight = qbarWeightX(d_qt, d_z);
// compute veto from weight and return
return !UseRandom::rndbool(weight);
}
void SMWDecayer::setRho(double r)
{
d_rho_ = r;
d_v_ = sqrt(1.-4.*d_rho_);
}
void SMWDecayer::setKtildeSymm() {
d_kt1_ = (1. + sqrt(1. - 4.*d_rho_))/2.;
setKtilde2();
}
void SMWDecayer::setKtilde2() {
double num = d_rho_ * d_kt1_ + 0.25 * d_v_ *(1.+d_v_)*(1.+d_v_);
double den = d_kt1_ - d_rho_;
d_kt2_ = num/den;
}
double SMWDecayer::getZfromX(double x1, double x2) {
double uval = u(x2);
double num = x1 - (2. - x2)*uval;
double den = sqrt(x2*x2 - 4.*d_rho_);
return uval + num/den;
}
double SMWDecayer::getKfromX(double x1, double x2) {
double zval = getZfromX(x1, x2);
return (1.-x2)/(zval*(1.-zval));
}
double SMWDecayer::MEV(double x1, double x2) {
// Vector part
double num = (x1+2.*d_rho_)*(x1+2.*d_rho_) + (x2+2.*d_rho_)*(x2+2.*d_rho_)
- 8.*d_rho_*(1.+2.*d_rho_);
double den = (1.+2.*d_rho_)*(1.-x1)*(1.-x2);
return (num/den - 2.*d_rho_/((1.-x1)*(1.-x1))
- 2*d_rho_/((1.-x2)*(1.-x2)))/d_v_;
}
double SMWDecayer::MEA(double x1, double x2) {
// Axial part
double num = (x1+2.*d_rho_)*(x1+2.*d_rho_) + (x2+2.*d_rho_)*(x2+2.*d_rho_)
+ 2.*d_rho_*((5.-x1-x2)*(5.-x1-x2) - 19.0 + 4*d_rho_);
double den = d_v_*d_v_*(1.-x1)*(1.-x2);
return (num/den - 2.*d_rho_/((1.-x1)*(1.-x1))
- 2*d_rho_/((1.-x2)*(1.-x2)))/d_v_;
}
double SMWDecayer::u(double x2) {
return 0.5*(1. + d_rho_/(1.-x2+d_rho_));
}
void SMWDecayer::
getXXbar(double kti, double z, double &x, double &xbar) {
double w = sqr(d_v_) + kti*(-1. + z)*z*(2. + kti*(-1. + z)*z);
if (w < 0) {
x = -1.;
xbar = -1;
} else {
x = (1. + sqr(d_v_)*(-1. + z) + sqr(kti*(-1. + z))*z*z*z
+ z*sqrt(w)
- kti*(-1. + z)*z*(2. + z*(-2 + sqrt(w))))/
(1. - kti*(-1. + z)*z + sqrt(w));
xbar = 1. + kti*(-1. + z)*z;
}
}
double SMWDecayer::qWeight(double x, double xbar) {
double rval;
double xg = 2. - xbar - x;
// always return one in the soft gluon region
if(xg < EPS_) return 1.0;
// check it is in the phase space
if((1.-x)*(1.-xbar)*(1.-xg) < d_rho_*xg*xg) return 0.0;
double k1 = getKfromX(x, xbar);
double k2 = getKfromX(xbar, x);
// Is it in the quark emission zone?
if(k1 < d_kt1_) {
rval = MEV(x, xbar)/PS(x, xbar);
// is it also in the anti-quark emission zone?
if(k2 < d_kt2_) rval *= 0.5;
return rval;
}
return 1.0;
}
double SMWDecayer::qbarWeight(double x, double xbar) {
double rval;
double xg = 2. - xbar - x;
// always return one in the soft gluon region
if(xg < EPS_) return 1.0;
// check it is in the phase space
if((1.-x)*(1.-xbar)*(1.-xg) < d_rho_*xg*xg) return 0.0;
double k1 = getKfromX(x, xbar);
double k2 = getKfromX(xbar, x);
// Is it in the antiquark emission zone?
if(k2 < d_kt2_) {
rval = MEV(x, xbar)/PS(xbar, x);
// is it also in the quark emission zone?
if(k1 < d_kt1_) rval *= 0.5;
return rval;
}
return 1.0;
}
double SMWDecayer::qWeightX(Energy qtilde, double z) {
double x, xb;
getXXbar(sqr(qtilde/d_Q_), z, x, xb);
// if exceptionally out of phase space, leave this emission, as there
// is no good interpretation for the soft ME correction.
if (x < 0 || xb < 0) return 1.0;
return qWeight(x, xb);
}
double SMWDecayer::qbarWeightX(Energy qtilde, double z) {
double x, xb;
getXXbar(sqr(qtilde/d_Q_), z, xb, x);
// see above in qWeightX.
if (x < 0 || xb < 0) return 1.0;
return qbarWeight(x, xb);
}
double SMWDecayer::PS(double x, double xbar) {
double u = 0.5*(1. + d_rho_ / (1.-xbar+d_rho_));
double z = u + (x - (2.-xbar)*u)/sqrt(xbar*xbar - 4.*d_rho_);
double brack = (1.+z*z)/(1.-z)- 2.*d_rho_/(1-xbar);
// interesting: the splitting function without the subtraction
// term. Actually gives a much worse approximation in the collinear
// limit. double brack = (1.+z*z)/(1.-z);
double den = (1.-xbar)*sqrt(xbar*xbar - 4.*d_rho_);
return brack/den;
}
double SMWDecayer::matrixElementRatio(const Particle & inpart, const ParticleVector & decay2,
const ParticleVector & decay3, MEOption,
ShowerInteraction inter) {
// extract partons and LO momentas
vector<tcPDPtr> partons(1,inpart.dataPtr());
vector<Lorentz5Momentum> lomom(1,inpart.momentum());
for(unsigned int ix=0;ix<2;++ix) {
partons.push_back(decay2[ix]->dataPtr());
lomom.push_back(decay2[ix]->momentum());
}
vector<Lorentz5Momentum> realmom(1,inpart.momentum());
for(unsigned int ix=0;ix<3;++ix) {
if(ix==2) partons.push_back(decay3[ix]->dataPtr());
realmom.push_back(decay3[ix]->momentum());
}
if(partons[0]->id()<0) {
swap(partons[1],partons[2]);
swap(lomom[1],lomom[2]);
swap(realmom[1],realmom[2]);
}
scale_ = sqr(inpart.mass());
double lome = loME(partons,lomom);
InvEnergy2 reme = realME(partons,realmom,inter);
double ratio = reme/lome*sqr(inpart.mass())*4.*Constants::pi;
if(inter==ShowerInteraction::QCD) ratio *= CF_;
return ratio;
}
double SMWDecayer::meRatio(tcPDVector partons,
vector<Lorentz5Momentum> momenta,
unsigned int iemitter, bool subtract) const {
Lorentz5Momentum q = momenta[1]+momenta[2]+momenta[3];
Energy2 Q2=q.m2();
Energy2 lambda = sqrt((Q2-sqr(momenta[1].mass()+momenta[2].mass()))*
(Q2-sqr(momenta[1].mass()-momenta[2].mass())));
InvEnergy2 D[2];
double lome(0.);
for(unsigned int iemit=0;iemit<2;++iemit) {
unsigned int ispect = iemit==0 ? 1 : 0;
Energy2 pipj = momenta[3 ] * momenta[1+iemit ];
Energy2 pipk = momenta[3 ] * momenta[1+ispect];
Energy2 pjpk = momenta[1+iemit] * momenta[1+ispect];
double y = pipj/(pipj+pipk+pjpk);
double z = pipk/( pipk+pjpk);
Energy mij = sqrt(2.*pipj+sqr(momenta[1+iemit].mass()));
Energy2 lamB = sqrt((Q2-sqr(mij+momenta[1+ispect].mass()))*
(Q2-sqr(mij-momenta[1+ispect].mass())));
Energy2 Qpk = q*momenta[1+ispect];
Lorentz5Momentum pkt =
lambda/lamB*(momenta[1+ispect]-Qpk/Q2*q)
+0.5/Q2*(Q2+sqr(momenta[1+ispect].mass())-sqr(momenta[1+ispect].mass()))*q;
Lorentz5Momentum pijt =
q-pkt;
double muj = momenta[1+iemit ].mass()/sqrt(Q2);
double muk = momenta[1+ispect].mass()/sqrt(Q2);
double vt = sqrt((1.-sqr(muj+muk))*(1.-sqr(muj-muk)))/(1.-sqr(muj)-sqr(muk));
double v = sqrt(sqr(2.*sqr(muk)+(1.-sqr(muj)-sqr(muk))*(1.-y))-4.*sqr(muk))
/(1.-y)/(1.-sqr(muj)-sqr(muk));
// dipole term
D[iemit] = 0.5/pipj*(2./(1.-(1.-z)*(1.-y))
-vt/v*(2.-z+sqr(momenta[1+iemit].mass())/pipj));
// matrix element
vector<Lorentz5Momentum> lomom(3);
lomom[0] = momenta[0];
if(iemit==0) {
lomom[1] = pijt;
lomom[2] = pkt ;
}
else {
lomom[2] = pijt;
lomom[1] = pkt ;
}
if(iemit==0) lome = loME(partons,lomom);
}
InvEnergy2 ratio = realME(partons,momenta,ShowerInteraction::QCD)/lome*abs(D[iemitter])
/(abs(D[0])+abs(D[1]));
if(subtract)
return Q2*(ratio-2.*D[iemitter]);
else
return Q2*ratio;
}
double SMWDecayer::loME(const vector<tcPDPtr> & partons,
const vector<Lorentz5Momentum> & momenta) const {
// compute the spinors
vector<VectorWaveFunction> vin;
vector<SpinorWaveFunction> aout;
vector<SpinorBarWaveFunction> fout;
VectorWaveFunction win (momenta[0],partons[0],incoming);
SpinorBarWaveFunction qkout(momenta[1],partons[1],outgoing);
SpinorWaveFunction qbout(momenta[2],partons[2],outgoing);
for(unsigned int ix=0;ix<2;++ix){
qkout.reset(ix);
fout.push_back(qkout);
qbout.reset(ix);
aout.push_back(qbout);
}
for(unsigned int ix=0;ix<3;++ix){
win.reset(ix);
vin.push_back(win);
}
// temporary storage of the different diagrams
// sum over helicities to get the matrix element
double total(0.);
for(unsigned int inhel=0;inhel<3;++inhel) {
for(unsigned int outhel1=0;outhel1<2;++outhel1) {
for(unsigned int outhel2=0;outhel2<2;++outhel2) {
Complex diag1 = FFWVertex_->evaluate(scale_,aout[outhel2],fout[outhel1],vin[inhel]);
total += norm(diag1);
}
}
}
// return the answer
return total;
}
InvEnergy2 SMWDecayer::realME(const vector<tcPDPtr> & partons,
const vector<Lorentz5Momentum> & momenta,
ShowerInteraction inter) const {
// compute the spinors
vector<VectorWaveFunction> vin;
vector<SpinorWaveFunction> aout;
vector<SpinorBarWaveFunction> fout;
vector<VectorWaveFunction> gout;
VectorWaveFunction win (momenta[0],partons[0],incoming);
SpinorBarWaveFunction qkout(momenta[1],partons[1],outgoing);
SpinorWaveFunction qbout(momenta[2],partons[2],outgoing);
VectorWaveFunction gluon(momenta[3],partons[3],outgoing);
for(unsigned int ix=0;ix<2;++ix){
qkout.reset(ix);
fout.push_back(qkout);
qbout.reset(ix);
aout.push_back(qbout);
gluon.reset(2*ix);
gout.push_back(gluon);
}
for(unsigned int ix=0;ix<3;++ix){
win.reset(ix);
vin.push_back(win);
}
vector<Complex> diag(3,0.);
double total(0.);
AbstractFFVVertexPtr vertex = inter==ShowerInteraction::QCD ? FFGVertex_ : FFPVertex_;
for(unsigned int inhel1=0;inhel1<3;++inhel1) {
for(unsigned int outhel1=0;outhel1<2;++outhel1) {
for(unsigned int outhel2=0;outhel2<2;++outhel2) {
for(unsigned int outhel3=0;outhel3<2;++outhel3) {
SpinorBarWaveFunction off1 =
vertex->evaluate(scale_,3,partons[1]->CC(),fout[outhel1],gout[outhel3]);
diag[0] = FFWVertex_->evaluate(scale_,aout[outhel2],off1,vin[inhel1]);
SpinorWaveFunction off2 =
vertex->evaluate(scale_,3,partons[2]->CC(),aout[outhel2],gout[outhel3]);
diag[1] = FFWVertex_->evaluate(scale_,off2,fout[outhel1],vin[inhel1]);
if(inter==ShowerInteraction::QED) {
VectorWaveFunction off3 =
WWWVertex_->evaluate(scale_,3,partons[0],vin[inhel1],gout[outhel3]);
diag[2] = FFWVertex_->evaluate(scale_,aout[outhel2],fout[outhel1],off3);
}
// sum of diagrams
Complex sum = std::accumulate(diag.begin(),diag.end(),Complex(0.));
// me2
total += norm(sum);
}
}
}
}
// divide out the coupling
total /= norm(vertex->norm());
// double g = sqrt(2.)*abs(FFWVertex_->norm());
// double xg = 2.*momenta[3].t()/momenta[0].mass();
// double xe,mue2;
// if(abs(partons[1]->id())==ParticleID::eminus) {
// xe = 2.*momenta[1].t()/momenta[0].mass();
// mue2 = sqr(momenta[1].mass()/momenta[0].mass());
// }
// else {
// xe = 2.*momenta[2].t()/momenta[0].mass();
// mue2 = sqr(momenta[2].mass()/momenta[0].mass());
// }
// double cg = -4. * g * g * (-pow(mue2, 3.) / 2. + (xg * xg / 4. + (xe / 2. + 1.) * xg + 5. / 2. * xe - 2.) * mue2 * mue2
// + (pow(xg, 3.) / 4. + (xe / 4. - 5. / 4.) * xg * xg + (-7. / 2. * xe + 3.) * xg - 3. * xe * xe
// + 11. / 2. * xe - 7. / 2.) * mue2 + (xg * xg / 2. + (xe - 2.) * xg + xe * xe - 2. * xe + 2.) * (-1. + xg + xe)) * (xe - mue2 - 1.) *
// pow(xg, -2.) * pow(-1. + xg + xe - mue2, -2.);
// cerr << "real " << cg/total << "\n";
// return the total
return total*UnitRemoval::InvE2;
}
double SMWDecayer::calculateRealEmission(double x1, double x2,
tcPDVector partons,
vector<Lorentz5Momentum> pin,
double phi, double muj,
double muk, int iemit,
bool subtract) const {
// calculate x3
double x3 = 2.-x1-x2;
double xT = sqrt(max(0.,sqr(x3)-0.25*sqr(sqr(x2)+sqr(x3)-sqr(x1)-4.*sqr(muk)+4.*sqr(muj))
/(sqr(x2)-4.*sqr(muk))));
// calculate the momenta
Energy M = mW_;
Lorentz5Momentum pspect(ZERO,ZERO,-0.5*M*sqrt(max(sqr(x2)-4.*sqr(muk),0.)),
0.5*M*x2,M*muk);
Lorentz5Momentum pemit (-0.5*M*xT*cos(phi),-0.5*M*xT*sin(phi),
0.5*M*sqrt(max(sqr(x1)-sqr(xT)-4.*sqr(muj),0.)),
0.5*M*x1,M*muj);
Lorentz5Momentum pgluon(0.5*M*xT*cos(phi), 0.5*M*xT*sin(phi),
0.5*M*sqrt(max(sqr(x3)-sqr(xT),0.)),0.5*M*x3,ZERO);
if(abs(pspect.z()+pemit.z()-pgluon.z())/M<1e-6)
pgluon.setZ(-pgluon.z());
else if(abs(pspect.z()-pemit.z()+pgluon.z())/M<1e-6)
pemit .setZ(- pemit.z());
// boost and rotate momenta
LorentzRotation eventFrame( ( pin[1] +
pin[2] ).findBoostToCM() );
unsigned int ispect = iemit==0 ? 2 : 1;
Lorentz5Momentum spectator = eventFrame*pin[ispect];
eventFrame.rotateZ( -spectator.phi() );
eventFrame.rotateY( -spectator.theta() );
eventFrame.invert();
vector<Lorentz5Momentum> momenta(3);
momenta[0] = pin[0];
momenta[ispect ] = eventFrame*pspect;
momenta[iemit+1] = eventFrame*pemit ;
momenta.push_back(eventFrame*pgluon);
// calculate the weight
double realwgt(0.);
if(1.-x1>1e-5 && 1.-x2>1e-5)
realwgt = meRatio(partons,momenta,iemit,subtract);
return realwgt;
}
diff --git a/Decay/Perturbative/SMZDecayer.cc b/Decay/Perturbative/SMZDecayer.cc
--- a/Decay/Perturbative/SMZDecayer.cc
+++ b/Decay/Perturbative/SMZDecayer.cc
@@ -1,1122 +1,1122 @@
// -*- C++ -*-
//
// SMZDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 SMZDecayer class.
//
#include "SMZDecayer.h"
#include "Herwig/Utilities/Maths.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/ParVector.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/DecayMode.h"
#include "Herwig/Decay/DecayVertex.h"
#include "ThePEG/Helicity/VectorSpinInfo.h"
#include "ThePEG/Helicity/FermionSpinInfo.h"
#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
#include "Herwig/Models/StandardModel/StandardModel.h"
#include "Herwig/Shower/RealEmissionProcess.h"
#include "Herwig/Decay/GeneralDecayMatrixElement.h"
#include <numeric>
using namespace Herwig;
using namespace ThePEG::Helicity;
const double SMZDecayer::EPS_=0.00000001;
SMZDecayer::SMZDecayer()
: quarkWeight_(5,0.), leptonWeight_(6,0.), CF_(4./3.),
NLO_(false) {
quarkWeight_[0] = 0.488029;
quarkWeight_[1] = 0.378461;
quarkWeight_[2] = 0.488019;
quarkWeight_[3] = 0.378027;
quarkWeight_[4] = 0.483207;
leptonWeight_[0] = 0.110709;
leptonWeight_[1] = 0.220276;
leptonWeight_[2] = 0.110708;
leptonWeight_[3] = 0.220276;
leptonWeight_[4] = 0.110458;
leptonWeight_[5] = 0.220276;
// intermediates
generateIntermediates(false);
// QED corrections
hasRealEmissionME(true);
hasOneLoopME(true);
}
void SMZDecayer::doinit() {
PerturbativeDecayer::doinit();
// get the vertices from the Standard Model object
tcHwSMPtr hwsm=dynamic_ptr_cast<tcHwSMPtr>(standardModel());
if(!hwsm) throw InitException() << "Must have Herwig StandardModel object in"
<< "SMZDecayer::doinit()"
<< Exception::runerror;
// cast the vertices
FFZVertex_ = dynamic_ptr_cast<FFVVertexPtr>(hwsm->vertexFFZ());
FFZVertex_->init();
FFGVertex_ = hwsm->vertexFFG();
FFGVertex_->init();
FFPVertex_ = hwsm->vertexFFP();
FFPVertex_->init();
gluon_ = getParticleData(ParticleID::g);
// now set up the decay modes
tPDPtr Z0 = getParticleData(ParticleID::Z0);
// loop over the quarks and the leptons
for(int istep=0;istep<11;istep+=10) {
for(int ix=1;ix<7;++ix) {
int iy=istep+ix;
if(iy==6) continue;
double maxWeight = iy<=6 ? quarkWeight_.at(ix-1) : leptonWeight_.at(iy-11);
tPDVector out = {getParticleData(-iy),getParticleData( iy)};
PhaseSpaceModePtr mode = new_ptr(PhaseSpaceMode(Z0,out,maxWeight));
addMode(mode);
}
}
}
int SMZDecayer::modeNumber(bool & cc,tcPDPtr parent,
const tPDVector & children) const {
int imode(-1);
if(children.size()!=2) return imode;
int id0=parent->id();
tPDVector::const_iterator pit = children.begin();
int id1=(**pit).id();
++pit;
int id2=(**pit).id();
// Z to quarks or leptons
cc =false;
if(id0!=ParticleID::Z0) return imode;
if(abs(id1)<6&&id1==-id2) {
imode=abs(id1)-1;
}
else if(abs(id1)>=11&&abs(id1)<=16&&id1==-id2) {
imode=abs(id1)-6;
}
cc = false;
return imode;
}
void SMZDecayer::persistentOutput(PersistentOStream & os) const {
os << FFZVertex_ << FFPVertex_ << FFGVertex_
<< quarkWeight_ << leptonWeight_ << NLO_
<< gluon_;
}
void SMZDecayer::persistentInput(PersistentIStream & is, int) {
is >> FFZVertex_ >> FFPVertex_ >> FFGVertex_
>> quarkWeight_ >> leptonWeight_ >> NLO_
>> gluon_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<SMZDecayer,PerturbativeDecayer>
describeHerwigSMZDecayer("Herwig::SMZDecayer", "HwPerturbativeDecay.so");
void SMZDecayer::Init() {
static ClassDocumentation<SMZDecayer> documentation
("The SMZDecayer class is the implementation of the decay"
" Z boson to the Standard Model fermions.");
static ParVector<SMZDecayer,double> interfaceZquarkMax
("QuarkMax",
"The maximum weight for the decay of the Z to quarks",
&SMZDecayer::quarkWeight_,
0, 0, 0, -10000, 10000, false, false, true);
static ParVector<SMZDecayer,double> interfaceZleptonMax
("LeptonMax",
"The maximum weight for the decay of the Z to leptons",
&SMZDecayer::leptonWeight_,
0, 0, 0, -10000, 10000, false, false, true);
static Switch<SMZDecayer,bool> interfaceNLO
("NLO",
"Whether to return the LO or NLO result",
&SMZDecayer::NLO_, false, false, false);
static SwitchOption interfaceNLOLO
(interfaceNLO,
"No",
"Leading-order result",
false);
static SwitchOption interfaceNLONLO
(interfaceNLO,
"Yes",
"NLO result",
true);
}
ParticleVector SMZDecayer::decay(const Particle & parent,
const tPDVector & children) const {
// generate the decay
bool cc;
unsigned int imode = modeNumber(cc,parent.dataPtr(),children);
ParticleVector output = generate(false,false,imode,parent);
if(output[0]->hasColour()) output[0]->antiColourNeighbour(output[1]);
else if(output[1]->hasColour()) output[1]->antiColourNeighbour(output[0]);
return output;
}
void SMZDecayer::
constructSpinInfo(const Particle & part, ParticleVector decay) const {
int iferm(1),ianti(0);
if(decay[0]->id()>0) swap(iferm,ianti);
VectorWaveFunction::constructSpinInfo(_vectors,const_ptr_cast<tPPtr>(&part),
incoming,true,false);
SpinorBarWaveFunction::
constructSpinInfo(_wavebar,decay[iferm],outgoing,true);
SpinorWaveFunction::
constructSpinInfo(_wave ,decay[ianti],outgoing,true);
}
// return the matrix element squared
double SMZDecayer::me2(const int,const Particle & part,
const tPDVector & outgoing,
const vector<Lorentz5Momentum> & momenta,
MEOption meopt) const {
if(!ME())
ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
int iferm(1),ianti(0);
if(outgoing[0]->id()>0) swap(iferm,ianti);
if(meopt==Initialize) {
VectorWaveFunction::calculateWaveFunctions(_vectors,_rho,
const_ptr_cast<tPPtr>(&part),
incoming,false);
// fix rho if no correlations
fixRho(_rho);
}
SpinorBarWaveFunction wbar(momenta[iferm],outgoing[iferm],Helicity::outgoing);
SpinorWaveFunction w (momenta[ianti],outgoing[ianti],Helicity::outgoing);
_wavebar.resize(2);
_wave .resize(2);
for(unsigned int ihel=0;ihel<2;++ihel) {
wbar.reset(ihel);
_wavebar[ihel] = wbar;
w.reset(ihel);
_wave [ihel] = w;
}
// compute the matrix element
Energy2 scale(sqr(part.mass()));
unsigned int ifm,ia,vhel;
for(ifm=0;ifm<2;++ifm) {
for(ia=0;ia<2;++ia) {
for(vhel=0;vhel<3;++vhel) {
if(iferm>ianti) (*ME())(vhel,ia,ifm)=
FFZVertex_->evaluate(scale,_wave[ia],_wavebar[ifm],_vectors[vhel]);
else (*ME())(vhel,ifm,ia)=
FFZVertex_->evaluate(scale,_wave[ia],_wavebar[ifm],_vectors[vhel]);
}
}
}
double output=(ME()->contract(_rho)).real()*UnitRemoval::E2/scale;
if(abs(outgoing[0]->id())<=6) output*=3.;
// if LO return
if(!NLO_) return output; // check decay products coloured, otherwise return
if(!outgoing[0]->coloured()) return output;
// inital masses, couplings etc
// fermion mass
Energy particleMass = outgoing[0]->mass();
// Z mass
mZ_ = part.mass();
// strong coupling
aS_ = SM().alphaS(sqr(mZ_));
// reduced mass
mu_ = particleMass/mZ_;
mu2_ = sqr(mu_);
// scale
scale_ = sqr(mZ_);
// compute the spinors
vector<SpinorWaveFunction> aout;
vector<SpinorBarWaveFunction> fout;
vector<VectorWaveFunction> vin;
SpinorBarWaveFunction qkout(momenta[0],outgoing[0],Helicity::outgoing);
SpinorWaveFunction qbout(momenta[1],outgoing[1],Helicity::outgoing);
VectorWaveFunction zin (part.momentum() ,part.dataPtr() ,incoming);
for(unsigned int ix=0;ix<2;++ix){
qkout.reset(ix);
fout.push_back(qkout);
qbout.reset(ix);
aout.push_back(qbout);
}
for(unsigned int ix=0;ix<3;++ix){
zin.reset(ix);
vin.push_back(zin);
}
// temporary storage of the different diagrams
// sum over helicities to get the matrix element
double total=0.;
if(mu_!=0.) {
LorentzPolarizationVector momDiff =
(momenta[0]-momenta[1])/2./(momenta[0].mass()+momenta[1].mass());
// scalars
Complex scalar1 = zin.wave().dot(momDiff);
for(unsigned int outhel1=0;outhel1<2;++outhel1) {
for(unsigned int outhel2=0;outhel2<2;++outhel2) {
for(unsigned int inhel=0;inhel<3;++inhel) {
// first the LO bit
Complex diag1 = FFZVertex_->evaluate(scale_,aout[outhel2],
fout[outhel1],vin[inhel]);
// extra stuff for NLO
LorentzPolarizationVector left =
aout[outhel2].wave().leftCurrent(fout[outhel1].wave());
LorentzPolarizationVector right =
aout[outhel2].wave().rightCurrent(fout[outhel1].wave());
Complex scalar =
aout[outhel2].wave().scalar(fout[outhel1].wave());
// nlo specific pieces
Complex diag3 =
Complex(0.,1.)*FFZVertex_->norm()*
(FFZVertex_->right()*( left.dot(zin.wave())) +
FFZVertex_-> left()*(right.dot(zin.wave())) -
( FFZVertex_-> left()+FFZVertex_->right())*scalar1*scalar);
// nlo piece
total += real(diag1*conj(diag3) + diag3*conj(diag1));
}
}
}
// rescale
total *= UnitRemoval::E2/scale_;
}
else {
total = ZERO;
}
// now for the NLO bit
double mu4 = sqr(mu2_);
double lmu = mu_!=0. ? log(mu_) : 0.;
double v = sqrt(1.-4.*mu2_),v2(sqr(v));
double omv = 4.*mu2_/(1.+v);
double f1,f2,fNS,VNS;
double r = omv/(1.+v);
double lr = mu_!=0. ? log(r) : 0.;
// normal form
if(mu_>1e-4) {
f1 = CF_*aS_/Constants::pi*
( +1. + 3.*log(0.5*(1.+v)) - 1.5*log(0.5*(1.+v2)) + sqr(Constants::pi)/6.
- 0.5*sqr(lr) - (1.+v2)/v*(lr*log(1.+v2) + sqr(Constants::pi)/12.
-0.5*log(4.*mu2_)*lr + 0.25*sqr(lr)));
fNS = -0.5*(1.+2.*v2)*lr/v + 1.5*lr - 2./3.*sqr(Constants::pi) + 0.5*sqr(lr)
+ (1.+v2)/v*(Herwig::Math::ReLi2(r) + sqr(Constants::pi)/3. - 0.25*sqr(lr)
+ lr*log((2.*v/ (1.+v))));
VNS = 1.5*log(0.5*(1.+v2))
+ 0.5*(1.+v2)/v*( 2.*lr*log(2.*(1.+v2)/sqr(1.+v))
+ 2.*Herwig::Math::ReLi2(sqr(r))
- 2.*Herwig::Math::ReLi2(2.*v/(1.+v)) - sqr(Constants::pi)/6.)
+ log(1.-mu_) - 2.*log(1.-2.*mu_) - 4.*mu2_/(1.+v2)*log(mu_/(1.-mu_))
- mu_/(1.-mu_)
+ 4.*(2.*mu2_-mu_)/(1.+v2) + 0.5*sqr(Constants::pi);
f2 = CF_*aS_/Constants::pi*mu2_*lr/v;
}
// small mass limit
else {
f1 = -CF_*aS_/Constants::pi/6.*
( - 6. - 24.*lmu*mu2_ - 15.*mu4 - 12.*mu4*lmu - 24.*mu4*sqr(lmu)
+ 2.*mu4*sqr(Constants::pi) - 12.*mu2_*mu4 - 96.*mu2_*mu4*sqr(lmu)
+ 8.*mu2_*mu4*sqr(Constants::pi) - 80.*mu2_*mu4*lmu);
fNS = - mu2_/18.*( + 36.*lmu - 36. - 45.*mu2_ + 216.*lmu*mu2_ - 24.*mu2_*sqr(Constants::pi)
+ 72.*mu2_*sqr(lmu) - 22.*mu4 + 1032.*mu4 * lmu
- 96.*mu4*sqr(Constants::pi) + 288.*mu4*sqr(lmu));
VNS = - mu2_/1260.*(-6930. + 7560.*lmu + 2520.*mu_ - 16695.*mu2_
+ 1260.*mu2_*sqr(Constants::pi)
+ 12600.*lmu*mu2_ + 1344.*mu_*mu2_ - 52780.*mu4 + 36960.*mu4*lmu
+ 5040.*mu4*sqr(Constants::pi) - 12216.*mu_*mu4);
f2 = CF_*aS_*mu2_/Constants::pi*( 2.*lmu + 4.*mu2_*lmu + 2.*mu2_ + 12.*mu4*lmu + 7.*mu4);
}
// add up bits for f1
f1 += CF_*aS_/Constants::pi*(fNS+VNS);
double realFact(0.);
for(int iemit=0;iemit<2;++iemit) {
// now for the real correction
double phi = UseRandom::rnd()*Constants::twopi;
// calculate y
double yminus = 0.;
double yplus = 1.-2.*mu_*(1.-mu_)/(1.-2*mu2_);
double y = yminus + UseRandom::rnd()*(yplus-yminus);
// calculate z
double v1 = sqrt(sqr(2.*mu2_+(1.-2.*mu2_)*(1.-y))-4.*mu2_)/(1.-2.*mu2_)/(1.-y);
double zplus = (1.+v1)*(1.-2.*mu2_)*y/2./(mu2_ +(1.-2.*mu2_)*y);
double zminus = (1.-v1)*(1.-2.*mu2_)*y/2./(mu2_ +(1.-2.*mu2_)*y);
double z = zminus + UseRandom::rnd()*(zplus-zminus);
double jac = (1.-y)*(yplus-yminus)*(zplus-zminus);
// calculate x1,x2
double x2 = 1. - y*(1.-2.*mu2_);
double x1 = 1. - z*(x2-2.*mu2_);
// copy the particle objects over for calculateRealEmission
- tcPDVector outgoing = {part.dataPtr(),outgoing[0],outgoing[1],gluon_};
+ tcPDVector oTemp = {part.dataPtr(),outgoing[0],outgoing[1],gluon_};
vector<Lorentz5Momentum> mom = {part.momentum(),momenta[0],momenta[1]};
// total real emission contribution
realFact += 0.25*jac*sqr(1.-2.*mu2_)/
sqrt(1.-4.*mu2_)/Constants::twopi
- *2.*CF_*aS_*calculateRealEmission(x1, x2, outgoing, mom, phi,
+ *2.*CF_*aS_*calculateRealEmission(x1, x2, oTemp, mom, phi,
iemit, true);
}
// the born + virtual + real
output = output*(1. + f1 + realFact) + f2*total;
return output;
}
void SMZDecayer::doinitrun() {
PerturbativeDecayer::doinitrun();
if(initialize()) {
for(unsigned int ix=0;ix<numberModes();++ix) {
if(ix<5) quarkWeight_ [ix ]=mode(ix)->maxWeight();
else if(ix<11) leptonWeight_[ix-5 ]=mode(ix)->maxWeight();
}
}
}
void SMZDecayer::dataBaseOutput(ofstream & output,
bool header) const {
if(header) output << "update decayers set parameters=\"";
for(unsigned int ix=0;ix<quarkWeight_.size();++ix) {
output << "newdef " << name() << ":QuarkMax " << ix << " "
<< quarkWeight_[ix] << "\n";
}
for(unsigned int ix=0;ix<leptonWeight_.size();++ix) {
output << "newdef " << name() << ":LeptonMax " << ix << " "
<< leptonWeight_[ix] << "\n";
}
// parameters for the PerturbativeDecayer base class
PerturbativeDecayer::dataBaseOutput(output,false);
if(header) output << "\n\" where BINARY ThePEGName=\""
<< fullName() << "\";" << endl;
}
InvEnergy2 SMZDecayer::
realEmissionME(unsigned int,const Particle &parent,
ParticleVector &children,
unsigned int iemitter,
double ctheta, double stheta,
const LorentzRotation & rot1,
const LorentzRotation & rot2) {
// check the number of products and parent
assert(children.size()==3 && parent.id()==ParticleID::Z0);
// the electric charge
double e = sqrt(SM().alphaEM()*4.*Constants::pi);
// azimuth of the photon
double phi = children[2]->momentum().phi();
// wavefunctions for the decaying particle in the rotated dipole frame
vector<VectorWaveFunction> vec1 = _vectors;
for(unsigned int ix=0;ix<vec1.size();++ix) {
vec1[ix].transform(rot1);
vec1[ix].transform(rot2);
}
// wavefunctions for the decaying particle in the rotated rest frame
vector<VectorWaveFunction> vec2 = _vectors;
for(unsigned int ix=0;ix<vec1.size();++ix) {
vec2[ix].transform(rot2);
}
// find the outgoing particle and antiparticle
unsigned int iferm(0),ianti(1);
if(children[iferm]->id()<0) swap(iferm,ianti);
// wavefunctions for the particles before the radiation
// wavefunctions for the outgoing fermion
SpinorBarWaveFunction wavebartemp;
Lorentz5Momentum ptemp = - _wavebar[0].momentum();
ptemp *= rot2;
if(ptemp.perp()/ptemp.e()<1e-10) {
ptemp.setX(ZERO);
ptemp.setY(ZERO);
}
wavebartemp = SpinorBarWaveFunction(ptemp,_wavebar[0].particle(),outgoing);
// wavefunctions for the outgoing antifermion
SpinorWaveFunction wavetemp;
ptemp = - _wave[0].momentum();
ptemp *= rot2;
if(ptemp.perp()/ptemp.e()<1e-10) {
ptemp.setX(ZERO);
ptemp.setY(ZERO);
}
wavetemp = SpinorWaveFunction(ptemp,_wave[0].particle(),outgoing);
// loop over helicities
vector<SpinorWaveFunction> wf_old;
vector<SpinorBarWaveFunction> wfb_old;
for(unsigned int ihel=0;ihel<2;++ihel) {
wavetemp.reset(ihel);
wf_old.push_back(wavetemp);
wavebartemp.reset(ihel);
wfb_old.push_back(wavebartemp);
}
// calculate the wave functions for the new fermions
// ensure the momenta have pT=0
for(unsigned int ix=0;ix<2;++ix) {
Lorentz5Momentum ptemp = children[ix]->momentum();
if(ptemp.perp()/ptemp.e()<1e-10) {
ptemp.setX(ZERO);
ptemp.setY(ZERO);
children[ix]->set5Momentum(ptemp);
}
}
// calculate the wavefunctions
vector<SpinorBarWaveFunction> wfb;
SpinorBarWaveFunction::calculateWaveFunctions(wfb,children[iferm],outgoing);
vector<SpinorWaveFunction> wf;
SpinorWaveFunction::calculateWaveFunctions (wf ,children[ianti],outgoing);
// wave functions for the photons
vector<VectorWaveFunction> photon;
VectorWaveFunction::calculateWaveFunctions(photon,children[2],outgoing,true);
// loop to calculate the matrix elements
Complex lome[3][2][2],diffme[3][2][2][2],summe[3][2][2][2];
Energy2 scale(sqr(parent.mass()));
Complex diff[2]={0.,0.};
Complex sum [2]={0.,0.};
for(unsigned int ifm=0;ifm<2;++ifm) {
for(unsigned int ia=0;ia<2;++ia) {
for(unsigned int vhel=0;vhel<3;++vhel) {
// calculation of the leading-order matrix element
Complex loamp = FFZVertex_->evaluate(scale,wf_old[ia],
wfb_old[ifm],vec2[vhel]);
Complex lotemp = FFZVertex_->evaluate(scale,wf[ia],
wfb[ifm],vec1[vhel]);
if(iferm>ianti) lome[vhel][ia][ifm] = loamp;
else lome[vhel][ifm][ia] = loamp;
// photon loop for the real emmision terms
for(unsigned int phel=0;phel<2;++phel) {
// radiation from the antifermion
// normal case with small angle treatment
if(children[2 ]->momentum().z()/
children[iferm]->momentum().z()>=ZERO && iemitter == iferm ) {
Complex dipole = e*double(children[iferm]->dataPtr()->iCharge())/3.*
UnitRemoval::E*loamp*
(children[iferm]->momentum()*photon[2*phel].wave())/
(children[iferm]->momentum()*children[2]->momentum());
// sum and difference
SpinorBarWaveFunction foff =
FFPVertex_->evaluateSmall(ZERO,3,children[iferm]->dataPtr()->CC(),
wfb[ifm],photon[2*phel],
ifm,2*phel,ctheta,phi,stheta,false);
diff[0] = FFZVertex_->evaluate(scale,wf[ia],foff,vec1[vhel]) +
e*double(children[iferm]->dataPtr()->iCharge())/3.*
UnitRemoval::E*(lotemp-loamp)*
(children[iferm]->momentum()*photon[2*phel].wave())/
(children[iferm]->momentum()*children[2]->momentum());
sum [0] = diff[0]+2.*dipole;
}
// special if fermion backwards
else {
SpinorBarWaveFunction foff =
FFPVertex_->evaluate(ZERO,3,children[iferm]->dataPtr()->CC(),
wfb[ifm],photon[2*phel]);
Complex diag =
FFZVertex_->evaluate(scale,wf[ia],foff,vec1[vhel]);
Complex dipole = e*double(children[iferm]->dataPtr()->iCharge())/3.*
UnitRemoval::E*loamp*
(children[iferm]->momentum()*photon[2*phel].wave())/
(children[iferm]->momentum()*children[2]->momentum());
diff[0] = diag-dipole;
sum [0] = diag+dipole;
}
// radiation from the anti fermion
// small angle case in general
if(children[2 ]->momentum().z()/
children[ianti]->momentum().z()>=ZERO && iemitter == ianti ) {
Complex dipole = e*double(children[ianti]->dataPtr()->iCharge())/3.*
UnitRemoval::E*loamp*
(children[ianti]->momentum()*photon[2*phel].wave())/
(children[ianti]->momentum()*children[2]->momentum());
// sum and difference
SpinorWaveFunction foff =
FFPVertex_->evaluateSmall(ZERO,3,children[ianti]->dataPtr()->CC(),
wf[ia],photon[2*phel],
ia,2*phel,ctheta,phi,stheta,false);
diff[1] = FFZVertex_->evaluate(scale,foff ,wfb[ifm],vec1[vhel]) +
e*double(children[ianti]->dataPtr()->iCharge())/3.*
UnitRemoval::E*(lotemp-loamp)*
(children[ianti]->momentum()*photon[2*phel].wave())/
(children[ianti]->momentum()*children[2]->momentum());
sum [1] = diff[1]+2.*dipole;
}
// special if fermion backwards after radiation
else {
SpinorWaveFunction foff =
FFPVertex_->evaluate(ZERO,3,children[ianti]->dataPtr()->CC(),
wf[ia],photon[2*phel]);
Complex diag =
FFZVertex_->evaluate(scale,foff ,wfb[ifm],vec1[vhel]);
Complex dipole = e*double(children[ianti]->dataPtr()->iCharge())/3.*
UnitRemoval::E*loamp*
(children[ianti]->momentum()*photon[2*phel].wave())/
(children[ianti]->momentum()*children[2]->momentum());
// sum and difference
diff[1] = diag - dipole;
sum [1] = diag + dipole;
}
// add to me
if(iferm>ianti) {
diffme[vhel][ia][ifm][phel] = diff[0] + diff[1];
summe [vhel][ia][ifm][phel] = sum[0] + sum[1] ;
}
else {
diffme [vhel][ifm][ia][phel] = diff[0] + diff[1];
summe [vhel][ifm][ia][phel] = sum[0] + sum[1] ;
}
}
}
}
}
// cerr << parent << "\n";
// for(unsigned int ix=0;ix<children.size();++ix) {
// cerr << *children[ix] << "\n";
// }
// _rho = RhoDMatrix(PDT::Spin1);
Complex lo(0.),difference(0.);
for(unsigned int vhel1=0;vhel1<3;++vhel1) {
for(unsigned int vhel2=0;vhel2<3;++vhel2) {
for(unsigned int ifm=0;ifm<2;++ifm) {
for(unsigned int ia=0;ia<2;++ia) {
lo += _rho(vhel1,vhel2)*lome[vhel1][ifm][ia]*conj(lome[vhel2][ifm][ia]);
for(unsigned int phel=0;phel<2;++phel) {
difference +=
_rho(vhel1,vhel2)*diffme[vhel1][ifm][ia][phel]*conj(summe[vhel2][ifm][ia][phel]);
}
}
}
}
}
// // analytic result
// double iCharge = children[0]->dataPtr()->iCharge()*
// children[1]->dataPtr()->iCharge()/9.;
// Energy2 ubar = 2.*children[0]->momentum()*children[2]->momentum();
// Energy2 tbar = 2.*children[1]->momentum()*children[2]->momentum();
// double mu2 = sqr(children[1]->mass()/parent.mass());
// double gL = (FFZVertex_->left() *FFZVertex_->norm()).real();
// double gR = (FFZVertex_->right()*FFZVertex_->norm()).real();
// Energy2 den = sqr(parent.mass())*(((sqr(gL)+sqr(gR))*(1-mu2)+6.*mu2*gL*gR));
// InvEnergy2 anal = -iCharge*( 2.*(ubar/tbar+tbar/ubar)/sqr(parent.mass())+
// 4.*mu2/den*((sqr(gL)+sqr(gR))*(1+ubar/tbar+tbar/ubar)
// -2.*gL*gR*(1.+2.*(ubar/tbar+tbar/ubar))));
// cerr << "testing ratio " << parent.PDGName()
// << " " << difference.real()/sqr(e)/lo.real()*UnitRemoval::InvE2/(anal) << "\n"
// << stheta << " " << ctheta << "\n";
return difference.real()/sqr(e)/lo.real()*UnitRemoval::InvE2;
}
double SMZDecayer::oneLoopVirtualME(unsigned int,
const Particle & parent,
const ParticleVector & children) {
assert(children.size()==2);
// velocities of the particles
double beta = sqrt(1.-4.*sqr(children[0]->mass()/parent.mass()));
double opb = 1.+beta;
double omb = 4.*sqr(children[0]->mass()/parent.mass())/opb;
// couplings
double gL = (FFZVertex_->left() *FFZVertex_->norm()).real();
double gR = (FFZVertex_->right()*FFZVertex_->norm()).real();
double gA = 0.5*(gL-gR);
double gV = 0.5*(gL+gR);
// correction terms
double ln = log(omb/opb);
double f1 = 1. + ln*beta;
double fA = 1. + ln/beta;
InvEnergy f2 = 0.5*sqrt(omb*opb)/parent.mass()/beta*ln;
// momentum difference for the loop
Lorentz5Momentum q = children[0]->momentum()-children[1]->momentum();
if(children[0]->id()<0) q *= -1.;
// spinors
vector<LorentzSpinor <SqrtEnergy> > sp;
vector<LorentzSpinorBar<SqrtEnergy> > sbar;
for(unsigned int ix=0;ix<2;++ix) {
sp .push_back( _wave[ix].dimensionedWave());
sbar.push_back(_wavebar[ix].dimensionedWave());
}
// polarization vectors
vector<LorentzPolarizationVector> pol;
for(unsigned int ix=0;ix<3;++ix)
pol.push_back(_vectors[ix].wave());
// matrix elements
complex<Energy> lome[3][2][2],loopme[3][2][2];
for(unsigned int vhel=0;vhel<3;++vhel) {
for(unsigned int ihel1=0;ihel1<2;++ihel1) {
for(unsigned int ihel2=0;ihel2<2;++ihel2) {
complex<Energy> vector =
sp[ihel1].generalCurrent(sbar[ihel2], 1.,1.).dot(pol[vhel]);
complex<Energy> axial =
sp[ihel1].generalCurrent(sbar[ihel2],-1.,1.).dot(pol[vhel]);
complex<Energy2> scalar =
sp[ihel1].scalar(sbar[ihel2])*(q*pol[vhel]);
lome [vhel][ihel1][ihel2] = gV* vector-gA* axial;
loopme[vhel][ihel1][ihel2] = gV*f1*vector-gA*fA*axial+scalar*f2*gV;
}
}
}
// sum sums
complex<Energy2> den(ZERO),num(ZERO);
for(unsigned int vhel1=0;vhel1<3;++vhel1) {
for(unsigned int vhel2=0;vhel2<3;++vhel2) {
for(unsigned int ihel1=0;ihel1<2;++ihel1) {
for(unsigned int ihel2=0;ihel2<2;++ihel2) {
num += _rho(vhel1,vhel2)*
( lome[vhel1][ihel1][ihel2]*conj(loopme[vhel2][ihel1][ihel2])+
loopme[vhel1][ihel1][ihel2]*conj( lome[vhel2][ihel1][ihel2]));
den += _rho(vhel1,vhel2)*
lome[vhel1][ihel1][ihel2]*conj(lome[vhel2][ihel1][ihel2]);
}
}
}
}
// prefactor
double iCharge = children[0]->dataPtr()->iCharge()*
children[1]->dataPtr()->iCharge()/9.;
double pre = 0.5*SM().alphaEM()*iCharge/Constants::pi;
// output
return pre*num.real()/den.real();
}
void SMZDecayer::
initializeMECorrection(RealEmissionProcessPtr born, double & initial,
double & final) {
// get the quark and antiquark
ParticleVector qq;
for(unsigned int ix=0;ix<born->bornOutgoing().size();++ix)
qq.push_back(born->bornOutgoing()[ix]);
// ensure quark first
if(qq[0]->id()<0) swap(qq[0],qq[1]);
// centre of mass energy
d_Q_ = (qq[0]->momentum() + qq[1]->momentum()).m();
// quark mass
d_m_ = 0.5*(qq[0]->momentum().m()+qq[1]->momentum().m());
// set the other parameters
setRho(sqr(d_m_/d_Q_));
setKtildeSymm();
// otherwise can do it
initial=1.;
final =1.;
}
bool SMZDecayer::softMatrixElementVeto(PPtr parent,
PPtr progenitor,
const bool & ,
const Energy & highestpT,
const vector<tcPDPtr> & ids,
const double & d_z,
const Energy & d_qt,
const Energy &) {
// check we should be applying the veto
if(parent->id()!=progenitor->id()||
ids[0]->id()!=ids[1]->id()||
ids[2]->id()!=ParticleID::g) return false;
// calculate pt
Energy2 d_m2 = parent->momentum().m2();
Energy pPerp = (1.-d_z)*sqrt( sqr(d_z*d_qt) - d_m2);
// if not hardest so far don't apply veto
if(pPerp<highestpT) return false;
// calculate the weight
double weight = 0.;
if(parent->id()>0) weight = qWeightX(d_qt, d_z);
else weight = qbarWeightX(d_qt, d_z);
// compute veto from weight and return
return !UseRandom::rndbool(weight);
}
void SMZDecayer::setRho(double r)
{
d_rho_ = r;
d_v_ = sqrt(1.-4.*d_rho_);
}
void SMZDecayer::setKtildeSymm() {
d_kt1_ = (1. + sqrt(1. - 4.*d_rho_))/2.;
setKtilde2();
}
void SMZDecayer::setKtilde2() {
double num = d_rho_ * d_kt1_ + 0.25 * d_v_ *(1.+d_v_)*(1.+d_v_);
double den = d_kt1_ - d_rho_;
d_kt2_ = num/den;
}
double SMZDecayer::getZfromX(double x1, double x2) {
double uval = u(x2);
double num = x1 - (2. - x2)*uval;
double den = sqrt(x2*x2 - 4.*d_rho_);
return uval + num/den;
}
double SMZDecayer::getKfromX(double x1, double x2) {
double zval = getZfromX(x1, x2);
return (1.-x2)/(zval*(1.-zval));
}
double SMZDecayer::MEV(double x1, double x2) {
// Vector part
double num = (x1+2.*d_rho_)*(x1+2.*d_rho_) + (x2+2.*d_rho_)*(x2+2.*d_rho_)
- 8.*d_rho_*(1.+2.*d_rho_);
double den = (1.+2.*d_rho_)*(1.-x1)*(1.-x2);
return (num/den - 2.*d_rho_/((1.-x1)*(1.-x1))
- 2*d_rho_/((1.-x2)*(1.-x2)))/d_v_;
}
double SMZDecayer::MEA(double x1, double x2) {
// Axial part
double num = (x1+2.*d_rho_)*(x1+2.*d_rho_) + (x2+2.*d_rho_)*(x2+2.*d_rho_)
+ 2.*d_rho_*((5.-x1-x2)*(5.-x1-x2) - 19.0 + 4*d_rho_);
double den = d_v_*d_v_*(1.-x1)*(1.-x2);
return (num/den - 2.*d_rho_/((1.-x1)*(1.-x1))
- 2*d_rho_/((1.-x2)*(1.-x2)))/d_v_;
}
double SMZDecayer::u(double x2) {
return 0.5*(1. + d_rho_/(1.-x2+d_rho_));
}
void SMZDecayer::
getXXbar(double kti, double z, double &x, double &xbar) {
double w = sqr(d_v_) + kti*(-1. + z)*z*(2. + kti*(-1. + z)*z);
if (w < 0) {
x = -1.;
xbar = -1;
} else {
x = (1. + sqr(d_v_)*(-1. + z) + sqr(kti*(-1. + z))*z*z*z
+ z*sqrt(w)
- kti*(-1. + z)*z*(2. + z*(-2 + sqrt(w))))/
(1. - kti*(-1. + z)*z + sqrt(w));
xbar = 1. + kti*(-1. + z)*z;
}
}
double SMZDecayer::qWeight(double x, double xbar) {
double rval;
double xg = 2. - xbar - x;
// always return one in the soft gluon region
if(xg < EPS_) return 1.0;
// check it is in the phase space
if((1.-x)*(1.-xbar)*(1.-xg) < d_rho_*xg*xg) return 0.0;
double k1 = getKfromX(x, xbar);
double k2 = getKfromX(xbar, x);
// Is it in the quark emission zone?
if(k1 < d_kt1_) {
rval = MEV(x, xbar)/PS(x, xbar);
// is it also in the anti-quark emission zone?
if(k2 < d_kt2_) rval *= 0.5;
return rval;
}
return 1.0;
}
double SMZDecayer::qbarWeight(double x, double xbar) {
double rval;
double xg = 2. - xbar - x;
// always return one in the soft gluon region
if(xg < EPS_) return 1.0;
// check it is in the phase space
if((1.-x)*(1.-xbar)*(1.-xg) < d_rho_*xg*xg) return 0.0;
double k1 = getKfromX(x, xbar);
double k2 = getKfromX(xbar, x);
// Is it in the antiquark emission zone?
if(k2 < d_kt2_) {
rval = MEV(x, xbar)/PS(xbar, x);
// is it also in the quark emission zone?
if(k1 < d_kt1_) rval *= 0.5;
return rval;
}
return 1.0;
}
double SMZDecayer::qWeightX(Energy qtilde, double z) {
double x, xb;
getXXbar(sqr(qtilde/d_Q_), z, x, xb);
// if exceptionally out of phase space, leave this emission, as there
// is no good interpretation for the soft ME correction.
if (x < 0 || xb < 0) return 1.0;
return qWeight(x, xb);
}
double SMZDecayer::qbarWeightX(Energy qtilde, double z) {
double x, xb;
getXXbar(sqr(qtilde/d_Q_), z, xb, x);
// see above in qWeightX.
if (x < 0 || xb < 0) return 1.0;
return qbarWeight(x, xb);
}
double SMZDecayer::PS(double x, double xbar) {
double u = 0.5*(1. + d_rho_ / (1.-xbar+d_rho_));
double z = u + (x - (2.-xbar)*u)/sqrt(xbar*xbar - 4.*d_rho_);
double brack = (1.+z*z)/(1.-z)- 2.*d_rho_/(1-xbar);
// interesting: the splitting function without the subtraction
// term. Actually gives a much worse approximation in the collinear
// limit. double brack = (1.+z*z)/(1.-z);
double den = (1.-xbar)*sqrt(xbar*xbar - 4.*d_rho_);
return brack/den;
}
double SMZDecayer::matrixElementRatio(const Particle & part, const ParticleVector & decay2,
const ParticleVector & decay3, MEOption,
ShowerInteraction inter) {
// extract partons and LO momentas
tcPDVector partons(1,part.dataPtr());
vector<Lorentz5Momentum> lomom(1,part.momentum());
for(unsigned int ix=0;ix<2;++ix) {
partons.push_back(decay2[ix]->dataPtr());
lomom.push_back(decay2[ix]->momentum());
}
vector<Lorentz5Momentum> realmom(1,part.momentum());
for(unsigned int ix=0;ix<3;++ix) {
if(ix==2) partons.push_back(decay3[ix]->dataPtr());
realmom.push_back(decay3[ix]->momentum());
}
if(partons[0]->id()<0) {
swap(partons[1],partons[2]);
swap(lomom[1],lomom[2]);
swap(realmom[1],realmom[2]);
}
scale_ = sqr(part.mass());
double lome = loME(partons,lomom);
InvEnergy2 reme = realME(partons,realmom,inter);
double ratio = reme/lome*sqr(part.mass())*4.*Constants::pi;
if(inter==ShowerInteraction::QCD) ratio *= CF_;
return ratio;
}
double SMZDecayer::meRatio(tcPDVector partons,
vector<Lorentz5Momentum> momenta,
unsigned int iemitter, bool subtract) const {
Lorentz5Momentum q = momenta[1]+momenta[2]+momenta[3];
Energy2 Q2=q.m2();
Energy2 lambda = sqrt((Q2-sqr(momenta[1].mass()+momenta[2].mass()))*
(Q2-sqr(momenta[1].mass()-momenta[2].mass())));
InvEnergy2 D[2];
double lome[2];
for(unsigned int iemit=0;iemit<2;++iemit) {
unsigned int ispect = iemit==0 ? 1 : 0;
Energy2 pipj = momenta[3 ] * momenta[1+iemit ];
Energy2 pipk = momenta[3 ] * momenta[1+ispect];
Energy2 pjpk = momenta[1+iemit] * momenta[1+ispect];
double y = pipj/(pipj+pipk+pjpk);
double z = pipk/( pipk+pjpk);
Energy mij = sqrt(2.*pipj+sqr(momenta[1+iemit].mass()));
Energy2 lamB = sqrt((Q2-sqr(mij+momenta[1+ispect].mass()))*
(Q2-sqr(mij-momenta[1+ispect].mass())));
Energy2 Qpk = q*momenta[1+ispect];
Lorentz5Momentum pkt =
lambda/lamB*(momenta[1+ispect]-Qpk/Q2*q)
+0.5/Q2*(Q2+sqr(momenta[1+ispect].mass())-sqr(momenta[1+ispect].mass()))*q;
Lorentz5Momentum pijt =
q-pkt;
double muj = momenta[1+iemit ].mass()/sqrt(Q2);
double muk = momenta[1+ispect].mass()/sqrt(Q2);
double vt = sqrt((1.-sqr(muj+muk))*(1.-sqr(muj-muk)))/(1.-sqr(muj)-sqr(muk));
double v = sqrt(sqr(2.*sqr(muk)+(1.-sqr(muj)-sqr(muk))*(1.-y))-4.*sqr(muk))
/(1.-y)/(1.-sqr(muj)-sqr(muk));
// dipole term
D[iemit] = 0.5/pipj*(2./(1.-(1.-z)*(1.-y))
-vt/v*(2.-z+sqr(momenta[1+iemit].mass())/pipj));
// matrix element
vector<Lorentz5Momentum> lomom(3);
lomom[0] = momenta[0];
if(iemit==0) {
lomom[1] = pijt;
lomom[2] = pkt ;
}
else {
lomom[2] = pijt;
lomom[1] = pkt ;
}
lome[iemit] = loME(partons,lomom);
}
InvEnergy2 ratio = realME(partons,momenta,ShowerInteraction::QCD)*abs(D[iemitter])
/(abs(D[0]*lome[0])+abs(D[1]*lome[1]));
if(subtract)
return Q2*(ratio-2.*D[iemitter]);
else
return Q2*ratio;
}
double SMZDecayer::loME(const tcPDVector & partons,
const vector<Lorentz5Momentum> & momenta) const {
// compute the spinors
vector<VectorWaveFunction> vin;
vector<SpinorWaveFunction> aout;
vector<SpinorBarWaveFunction> fout;
VectorWaveFunction zin (momenta[0],partons[0],incoming);
SpinorBarWaveFunction qkout(momenta[1],partons[1],outgoing);
SpinorWaveFunction qbout(momenta[2],partons[2],outgoing);
for(unsigned int ix=0;ix<2;++ix){
qkout.reset(ix);
fout.push_back(qkout);
qbout.reset(ix);
aout.push_back(qbout);
}
for(unsigned int ix=0;ix<3;++ix){
zin.reset(ix);
vin.push_back(zin);
}
// temporary storage of the different diagrams
// sum over helicities to get the matrix element
double total(0.);
for(unsigned int inhel=0;inhel<3;++inhel) {
for(unsigned int outhel1=0;outhel1<2;++outhel1) {
for(unsigned int outhel2=0;outhel2<2;++outhel2) {
Complex diag1 = FFZVertex_->evaluate(scale_,aout[outhel2],fout[outhel1],vin[inhel]);
total += norm(diag1);
}
}
}
// return the answer
return total;
}
InvEnergy2 SMZDecayer::realME(const tcPDVector & partons,
const vector<Lorentz5Momentum> & momenta,
ShowerInteraction inter) const {
AbstractFFVVertexPtr vertex = inter==ShowerInteraction::QCD ?
FFGVertex_ : FFPVertex_;
// compute the spinors
vector<VectorWaveFunction> vin;
vector<SpinorWaveFunction> aout;
vector<SpinorBarWaveFunction> fout;
vector<VectorWaveFunction> gout;
VectorWaveFunction zin (momenta[0],partons[0],incoming);
SpinorBarWaveFunction qkout(momenta[1],partons[1],outgoing);
SpinorWaveFunction qbout(momenta[2],partons[2],outgoing);
VectorWaveFunction gluon(momenta[3],partons[3],outgoing);
for(unsigned int ix=0;ix<2;++ix){
qkout.reset(ix);
fout.push_back(qkout);
qbout.reset(ix);
aout.push_back(qbout);
gluon.reset(2*ix);
gout.push_back(gluon);
}
for(unsigned int ix=0;ix<3;++ix){
zin.reset(ix);
vin.push_back(zin);
}
vector<Complex> diag(2,0.);
double total(0.);
for(unsigned int inhel1=0;inhel1<3;++inhel1) {
for(unsigned int outhel1=0;outhel1<2;++outhel1) {
for(unsigned int outhel2=0;outhel2<2;++outhel2) {
for(unsigned int outhel3=0;outhel3<2;++outhel3) {
SpinorBarWaveFunction off1 =
vertex->evaluate(scale_,3,partons[1]->CC(),fout[outhel1],gout[outhel3]);
diag[0] = FFZVertex_->evaluate(scale_,aout[outhel2],off1,vin[inhel1]);
SpinorWaveFunction off2 =
vertex->evaluate(scale_,3,partons[2]->CC(),aout[outhel2],gout[outhel3]);
diag[1] = FFZVertex_->evaluate(scale_,off2,fout[outhel1],vin[inhel1]);
// sum of diagrams
Complex sum = std::accumulate(diag.begin(),diag.end(),Complex(0.));
// me2
total += norm(sum);
}
}
}
}
// divide out the coupling
total /= norm(vertex->norm());
// return the total
return total*UnitRemoval::InvE2;
}
double SMZDecayer::calculateRealEmission(double x1, double x2,
vector<PPtr> hardProcess,
double phi,
bool subtract) const {
// make partons data object for meRatio
tcPDVector partons (3);
for(int ix=0; ix<3; ++ix)
partons[ix] = hardProcess[ix]->dataPtr();
partons.push_back(gluon_);
// calculate x3
double x3 = 2.-x1-x2;
double xT = sqrt(max(0.,sqr(x3) -0.25*sqr(sqr(x2)+sqr(x3)-sqr(x1))/(sqr(x2)-4.*mu2_)));
// calculate the momenta
Energy M = mZ_;
Lorentz5Momentum pspect(ZERO,ZERO,-0.5*M*sqrt(max(sqr(x2)-4.*mu2_,0.)),0.5*M*x2,M*mu_);
Lorentz5Momentum pemit (-0.5*M*xT*cos(phi),-0.5*M*xT*sin(phi),
0.5*M*sqrt(max(sqr(x1)-sqr(xT)-4.*mu2_,0.)),0.5*M*x1,M*mu_);
Lorentz5Momentum pgluon(0.5*M*xT*cos(phi), 0.5*M*xT*sin(phi),
0.5*M*sqrt(max(sqr(x3)-sqr(xT),0.)),0.5*M*x3,ZERO);
if(abs(pspect.z()+pemit.z()-pgluon.z())/M<1e-6)
pgluon.setZ(-pgluon.z());
else if(abs(pspect.z()-pemit.z()+pgluon.z())/M<1e-6)
pemit .setZ(- pemit.z());
// loop over the possible emitting partons
double realwgt(0.);
for(unsigned int iemit=0;iemit<2;++iemit) {
// boost and rotate momenta
LorentzRotation eventFrame( ( hardProcess[1]->momentum() +
hardProcess[2]->momentum() ).findBoostToCM() );
Lorentz5Momentum spectator = eventFrame*hardProcess[iemit+1]->momentum();
eventFrame.rotateZ( -spectator.phi() );
eventFrame.rotateY( -spectator.theta() );
eventFrame.invert();
vector<Lorentz5Momentum> momenta(3);
momenta[0] = hardProcess[0]->momentum();
if(iemit==0) {
momenta[2] = eventFrame*pspect;
momenta[1] = eventFrame*pemit ;
}
else {
momenta[1] = eventFrame*pspect;
momenta[2] = eventFrame*pemit ;
}
momenta.push_back(eventFrame*pgluon);
// calculate the weight
if(1.-x1>1e-5 && 1.-x2>1e-5)
realwgt += meRatio(partons,momenta,iemit,subtract);
}
// total real emission contribution
return realwgt;
}
double SMZDecayer::calculateRealEmission(double x1, double x2,
tcPDVector partons,
vector<Lorentz5Momentum> pin,
double phi,
bool subtract,
int emitter) const {
// calculate x3
double x3 = 2.-x1-x2;
double xT = sqrt(max(0.,sqr(x3) -0.25*sqr(sqr(x2)+sqr(x3)-sqr(x1))/(sqr(x2)-4.*mu2_)));
// calculate the momenta
Energy M = mZ_;
Lorentz5Momentum pspect(ZERO,ZERO,-0.5*M*sqrt(max(sqr(x2)-4.*mu2_,0.)),0.5*M*x2,M*mu_);
Lorentz5Momentum pemit (-0.5*M*xT*cos(phi),-0.5*M*xT*sin(phi),
0.5*M*sqrt(max(sqr(x1)-sqr(xT)-4.*mu2_,0.)),0.5*M*x1,M*mu_);
Lorentz5Momentum pgluon( 0.5*M*xT*cos(phi), 0.5*M*xT*sin(phi),
0.5*M*sqrt(max(sqr(x3)-sqr(xT),0.)),0.5*M*x3,ZERO);
if(abs(pspect.z()+pemit.z()-pgluon.z())/M<1e-6)
pgluon.setZ(-pgluon.z());
else if(abs(pspect.z()-pemit.z()+pgluon.z())/M<1e-6)
pemit .setZ(- pemit.z());
// boost and rotate momenta
LorentzRotation eventFrame( ( pin[1]+pin[2] ).findBoostToCM() );
unsigned int ispect = emitter==0 ? 2 : 1;
Lorentz5Momentum spectator = eventFrame*pin[ispect];
eventFrame.rotateZ( -spectator.phi() );
eventFrame.rotateY( -spectator.theta() );
eventFrame.invert();
vector<Lorentz5Momentum> momenta(3);
momenta[0] = pin[0];
momenta[ispect ] = eventFrame*pspect;
momenta[emitter+1] = eventFrame*pemit ;
momenta.push_back(eventFrame*pgluon);
// calculate the weight
double realwgt(0.);
if(1.-x1>1e-5 && 1.-x2>1e-5)
realwgt = meRatio(partons,momenta,emitter,subtract);
// total real emission contribution
return realwgt;
}
diff --git a/Decay/Radiation/FFDipole.cc b/Decay/Radiation/FFDipole.cc
--- a/Decay/Radiation/FFDipole.cc
+++ b/Decay/Radiation/FFDipole.cc
@@ -1,950 +1,948 @@
// -*- C++ -*-
//
// FFDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FFDipole class.
//
#include "FFDipole.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Utilities/Debug.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "YFSFormFactors.h"
#include "Herwig/Decay/PhaseSpaceMode.h"
#include "Herwig/Decay/DecayIntegrator.h"
using namespace Herwig;
void FFDipole::persistentOutput(PersistentOStream & os) const {
os << ounit(_emin,GeV) << ounit(_eminrest,GeV) << ounit(_eminlab,GeV)
<< _maxwgt << _weightOutput
<< _mode << _maxtry << _energyopt << _betaopt << _dipoleopt;
}
void FFDipole::persistentInput(PersistentIStream & is, int) {
is >> iunit(_emin,GeV) >> iunit(_eminrest,GeV) >> iunit(_eminlab,GeV)
>> _maxwgt >> _weightOutput
>> _mode >> _maxtry >> _energyopt >> _betaopt >> _dipoleopt;
}
-FFDipole::~FFDipole() {}
-
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<FFDipole,Interfaced>
describeHerwigFFDipole("Herwig::FFDipole", "HwSOPHTY.so");
void FFDipole::Init() {
static ClassDocumentation<FFDipole> documentation
("The FFDipole class implements the final-final dipole for the SOPTHY algorithm");
static Switch<FFDipole,unsigned int> interfaceUnWeight
("UnWeight",
"Control the type of unweighting to perform, only one should be used the"
" other options are for debugging purposes.",
&FFDipole::_mode, 1, false, false);
static SwitchOption interfaceUnWeightNoUnweighting
(interfaceUnWeight,
"NoUnweighting",
"Perform no unweighting",
0);
static SwitchOption interfaceUnWeightAllWeights
(interfaceUnWeight,
"AllWeights",
"Include all the weights",
1);
static SwitchOption interfaceUnWeightNoJacobian
(interfaceUnWeight,
"NoJacobian",
"Only include the dipole and YFS weights",
2);
static SwitchOption interfaceUnWeightDipole
(interfaceUnWeight,
"Dipole",
"Only include the dipole weight",
3);
static SwitchOption interfaceUnWeightYFS
(interfaceUnWeight,
"YFS",
"Only include the YFS weight",
4);
static SwitchOption interfaceUnWeightNLO
(interfaceUnWeight,
"NLO",
"Weight to get the stict NLO rate",
5);
static Parameter<FFDipole,unsigned int> interfaceMaximumTries
("MaximumTries",
"Maximum number of attempts to unweight",
&FFDipole::_maxtry, 500, 10, 100000,
false, false, Interface::limited);
static Parameter<FFDipole,Energy> interfaceMinimumEnergyBoosted
("MinimumEnergyBoosted",
"The minimum energy of the photons in the boosted frame in which"
" they are generated.",
&FFDipole::_emin, MeV, 1.e-6*MeV, ZERO, 100.0*MeV,
false, false, Interface::limited);
static Parameter<FFDipole,Energy> interfaceMinimumEnergyRest
("MinimumEnergyRest",
"The minimum energy of the photons in the rest frame of the decaying particle",
&FFDipole::_eminrest, MeV, 100.0*MeV, 1.0*MeV, 10000.0*MeV,
false, false, Interface::limited);
static Parameter<FFDipole,Energy> interfaceMinimumEnergyLab
("MinimumEnergyLab",
"The minimum energy of the photons in the lab frame",
&FFDipole::_eminlab, MeV, 100.0*MeV, 1.0*MeV, 10000.0*MeV,
false, false, Interface::limited);
static Parameter<FFDipole,double> interfaceMaximumWeight
("MaximumWeight",
"The maximum weight for unweighting",
&FFDipole::_maxwgt, 7.0, 0.0, 100.0,
false, false, Interface::limited);
static Switch<FFDipole,unsigned int> interfaceEnergyCutOff
("EnergyCutOff",
"The type of cut-off on the photon energy to apply",
&FFDipole::_energyopt, 1, false, false);
static SwitchOption interfaceEnergyCutOffBoostedFrame
(interfaceEnergyCutOff,
"BoostedFrame",
"Only apply cut-off in boosted frame",
0);
static SwitchOption interfaceEnergyCutOffRestFrame
(interfaceEnergyCutOff,
"RestFrame",
"Apply cut-off in rest frame",
1);
static SwitchOption interfaceEnergyCutOff2
(interfaceEnergyCutOff,
"LabFrame",
"Apply cut-off in lab frame",
2);
static Switch<FFDipole,unsigned int> interfaceBetaOption
("BetaOption",
"Option for the inclusive of the higher beta coefficients",
&FFDipole::_betaopt, 4, false, false);
static SwitchOption interfaceBetaOptionNone
(interfaceBetaOption,
"None",
"No higher betas included",
0);
static SwitchOption interfaceBetaOptionCollinear
(interfaceBetaOption,
"Collinear",
"Include the collinear approx",
1);
static SwitchOption interfaceBetaOptionCollinearVirtA
(interfaceBetaOption,
"CollinearVirtualA",
"Include the collinear approx with virtual corrections",
2);
static SwitchOption interfaceBetaOptionCollinearVirtB
(interfaceBetaOption,
"CollinearVirtualB",
"Include the collinear approx with virtual corrections",
3);
static SwitchOption interfaceBetaOptionExact
(interfaceBetaOption,
"Exact",
"Include the exact higher order terms if available",
4);
static Switch<FFDipole,unsigned int> interfaceDipoleOption
("DipoleOption",
"Option for generating the primary dipole distribution",
&FFDipole::_dipoleopt, 0, false, false);
static SwitchOption interfaceDipoleOptionNoMass
(interfaceDipoleOption,
"NoMass",
"Don't include the mass terms in the primary distribution",
0);
static SwitchOption interfaceDipoleOptionMass
(interfaceDipoleOption,
"Mass",
"Include the mass terms in the primary distribution",
1);
static Switch<FFDipole,bool> interfaceWeightOutput
("WeightOutput",
"Whether or not to output the average weight for testing",
&FFDipole::_weightOutput, false, false, false);
static SwitchOption interfaceWeightOutputNo
(interfaceWeightOutput,
"No",
"Don't output the average",
false);
static SwitchOption interfaceWeightOutputYes
(interfaceWeightOutput,
"Yes",
"Output the average",
true);
}
void FFDipole::printDebugInfo(const Particle & p,
const ParticleVector & children,
double wgt) const {
generator()->log() << "Input masses "
<< p.mass()/GeV << " -> "
<< children[0]->mass()/GeV << " "
<< children[1]->mass()/GeV << '\n';
generator()->log() << "Momenta\n";
generator()->log() << "parent " << p.momentum()/GeV << '\n';
for(unsigned int ix=0;ix<2;++ix)
generator()->log() << "charged " << ix << " "
<< _qnewlab[ix]/GeV << " "
<< children[ix]->momentum()/GeV << '\n';
for(unsigned int ix=0;ix<_multiplicity;++ix) {
generator()->log() << "photons " << ix << " "
<< "phocut " << _photcut[ix] << ' '
<< _llab[ix]/GeV << '\n';
}
generator()->log() << "wgt : " << wgt << '\n';
generator()->log() << "_mewgt : " << _mewgt << '\n';
generator()->log() << "_jacobianwgt: " << _jacobianwgt << '\n';
generator()->log() << "_yfswgt : " << _yfswgt << '\n';
generator()->log() << "_dipolewgt : " << _dipolewgt << '\n';
generator()->log() << "dipoleopt : " << _dipoleopt << '\n';
}
ParticleVector FFDipole::generatePhotons(const Particle & p,
ParticleVector children,
tDecayIntegratorPtr decayer) {
_parent = const_ptr_cast<tPPtr>(&p);
// set the decayer
_decayer=decayer;
// set parameters which won't change in the event loop
// masses of the particles
_m[0] = p.mass();
_m[1] = children[0]->mass();
_m[2] = children[1]->mass();
// set the maximum photon energy (exact - no approximations here).
_emax=(0.5*(_m[0]-sqr(_m[1]+_m[2])/_m[0]))*_m[0]/(_m[1]+_m[2]);
// check masses non-zero
for(unsigned int ix=0;ix<2;++ix) {
if(children[ix]->mass()<1e-4*GeV) {
ostringstream message;
message << "FFDipole::generatePhotons() trying to generate QED radiation from "
<< children[ix]->dataPtr()->PDGName() << "\n with mass " << children[ix]->mass()/GeV
<< "which is much smaller than the mass of the electron.\n"
<< "This is probably due to reading events from a LHEF,\nskipping radiation in this case.\n";
generator()->logWarning( Exception(message.str(), Exception::warning));
return children;
}
}
// momenta before radiation in lab
for(unsigned int ix=0;ix<2;++ix)
_qlab[ix]=children[ix]->momentum();
// get the charges of the particles in units of the positron charge
_charge=children[0]->dataPtr()->iCharge()*children[1]->dataPtr()->iCharge()/9.;
// boost the momenta to the rest frame
Boost boostv(-p.momentum().boostVector());
// boost the particles to the parent rest frame
// and set the initial momenta of the charged particles
// in the dipole rest frame: currently this is the same
// as the boson rest frame...
for(unsigned int ix=0;ix<2;++ix) {
children[ix]->deepBoost(boostv);
_qdrf[ix]=children[ix]->momentum();
_qprf[ix]=children[ix]->momentum();
}
_parent->boost(boostv);
// perform the unweighting
double wgt;
unsigned int ntry(0);
do {
++ntry;
wgt = makePhotons(-boostv,children);
// Error checks
if ( std::isnan(wgt) ) {
generator()->log() << "Infinite weight for decay "
<< p.PDGName() << " "
<< children[0]->PDGName()
<< " " << children[1]->PDGName()
<< '\n';
wgt = 0.0;
}
else if ( wgt < 0.0 && _mode != 5 ) {
generator()->log() << "Negative weight for decay "
<< p.PDGName() << " "
<< children[0]->PDGName()
<< " " << children[1]->PDGName()
<< "in FFDipole: Weight = " << wgt << '\n';
if ( Debug::level )
printDebugInfo(p,children,wgt);
}
else if ( wgt > _maxwgt ) {
generator()->log() << "Weight "<< wgt<<" exceeds maximum for decay "
<< p.PDGName() << ' '
<< children[0]->PDGName()
<< " " << children[1]->PDGName()
<< " in FFDipole:\nresetting maximum weight.\n"
<< "Old Maximum = " << _maxwgt;
_maxwgt = min(1.1 * wgt, 10.0);
generator()->log() << " New Maximum = " << wgt << '\n';
if ( Debug::level && _mode!=5 )
printDebugInfo(p,children,wgt);
}
// End of error checks
_wgtsum += wgt;
_wgtsq += sqr(wgt);
++_nweight;
}
while ( wgt<(_maxwgt*UseRandom::rnd()) && ntry<_maxtry );
if(ntry>=_maxtry) {
generator()->log() << "FFDipole failed to generate QED radiation for the decay "
<< p.PDGName() << " -> "
<< children[0]->PDGName() << " "
<< children[1]->PDGName() << '\n';
_parent->boost(-boostv);
for(unsigned int ix=0;ix<2;++ix)
children[ix]->deepBoost(-boostv);
return children;
}
// produce products after radiation if needed
if(_multiplicity>0) {
// change the momenta of the children, they are currently
// in original rest frame
for(unsigned int ix=0;ix<2;++ix) {
// unit vector along direction
Boost br = children[ix]->momentum().vect().unit();
// calculate the boost vector using expression accurate for beta->1
double beta(sqrt((_qdrf[ix].e()+_m[ix+1])*(_qdrf[ix].e()-_m[ix+1]))/
_qdrf[ix].e());
double ombeta(sqr(_m[ix+1]/_qdrf[ix].e())/(1.+beta));
double betap(sqrt((_qnewdrf[ix].e()+_m[ix+1])*(_qnewdrf[ix].e()-_m[ix+1]))
/_qnewdrf[ix].e());
double ombetap(sqr(_m[ix+1]/_qnewdrf[ix].e())/(1.+betap));
// boost to get correct momentum in dipole rest frame
double bv = -(ombetap-ombeta)/(beta*ombetap + ombeta);
br *= bv;
children[ix]->deepBoost(br);
// boost to the parent rest frame
Lorentz5Momentum pnew(_bigLdrf);
pnew.setMass(_m[0]);
pnew.rescaleEnergy();
br = pnew.findBoostToCM();
children[ix]->deepBoost(br);
// boost back to the lab
children[ix]->deepBoost(-boostv);
}
// add the photons to the event record
tcPDPtr photon=getParticleData(ParticleID::gamma);
for(unsigned int ix=0;ix<_multiplicity;++ix) {
// add if not removed because energy too low
if(!_photcut[ix]) {
PPtr newphoton=new_ptr(Particle(photon));
newphoton->set5Momentum(_llab[ix]);
children.push_back(newphoton);
}
}
_parent->boost(-boostv);
//printDebugInfo(p, children, wgt);
return children;
}
// otherwise just return the original particles
else {
for(unsigned int ix=0;ix<2;++ix)
children[ix]->deepBoost(-boostv);
_parent->boost(-boostv);
return children;
}
}
// member which generates the photons
double FFDipole::makePhotons(const Boost & boostv,
const ParticleVector & children) {
// set the initial parameters
// number of photons (zero)
_multiplicity=0;
// zero size of photon vectors
_ldrf.clear();
_lprf.clear();
_llab.clear();
// zero size of angle storage
_sinphot.clear();
_cosphot.clear();
_photcut.clear();
_photonwgt.clear();
// zero total momenta of the photons
_bigLdrf=Lorentz5Momentum();
_bigLprf=Lorentz5Momentum();
// set the initial values of the reweighting factors to one
_dipolewgt = 1.0;
_yfswgt = 1.0;
_jacobianwgt = 1.0;
_mewgt = 1.0;
// calculate the velocities of the charged particles (crude/overvalued)
double beta1(sqrt((_qdrf[0].e()+_m[1])*(_qdrf[0].e()-_m[1]))/_qdrf[0].e());
double beta2(sqrt((_qdrf[1].e()+_m[2])*(_qdrf[1].e()-_m[2]))/_qdrf[1].e());
// calculate 1-beta to avoid numerical problems
double ombeta1(sqr(_m[1]/_qdrf[0].e())/(1.+beta1));
double ombeta2(sqr(_m[2]/_qdrf[1].e())/(1.+beta2));
// calculate the average photon multiplicity
double aver(YFSFormFactors::nbarFF(beta1,ombeta1,beta2,ombeta2,_charge,
_emax,_emin,_dipoleopt==1));
// calculate the number of photons using the poisson
_multiplicity = _mode !=5 ? UseRandom::rndPoisson(aver) : 1;
// calculate the first part of the YFS factor
// (N.B. crude form factor is just exp(-aver) to get a poisson)
_yfswgt *= exp(aver);
// if photons produced
if(_multiplicity>0) {
_photonwgt.resize(_multiplicity);
// generate the photon momenta with respect to q1
// keeping track of the weight
for(unsigned int ix=0;ix<_multiplicity;++ix)
_photonwgt[ix] = photon(beta1,ombeta1,beta2,ombeta2);
// rotate the photons so in dipole rest frame rather
// than angle measured w.r.t q1 first work out the rotation
SpinOneLorentzRotation rotation;
rotation.setRotateZ(-_qdrf[0].phi());
rotation.rotateY(_qdrf[0].theta());
rotation.rotateZ(_qdrf[0].phi());
// rotate the total
_bigLdrf *= rotation;
// rotate the photons
for(unsigned int ix=0;ix<_multiplicity;++ix)
_ldrf[ix]*=rotation;
// boost the momenta without any removal of low energy photons
// resize arrays
_photcut.resize(_multiplicity,false);
_lprf.resize(_multiplicity);
_llab.resize(_multiplicity);
// perform the boost
if(!boostMomenta(boostv)){return 0.;}
// apply the cut on the photon energy if needed
unsigned int nremoved(removePhotons());
// redo the boost if we have removed photons
if(nremoved!=0){if(!boostMomenta(boostv)){return 0.;}}
// form factor part of the removal term to remove existing cut
if(_energyopt!=0) _dipolewgt *=
YFSFormFactors::exponentialYFSFF(beta1,ombeta1,beta2,ombeta2,
_qdrf[0].e(),_qdrf[1].e(),
_m[1],_m[2],_m[0]*_m[0],
_charge,_emin);
// calculate the new dipole weight
// calculate velocities and 1-velocites
beta1=sqrt((_qnewdrf[0].e()+_m[1])*(_qnewdrf[0].e()-_m[1]))/_qnewdrf[0].e();
beta2=sqrt((_qnewdrf[1].e()+_m[2])*(_qnewdrf[1].e()-_m[2]))/_qnewdrf[1].e();
ombeta1=sqr(_m[1]/_qnewdrf[0].e())/(1.+beta1);
ombeta2=sqr(_m[2]/_qnewdrf[1].e())/(1.+beta2);
for(unsigned int ix=0;ix<_multiplicity;++ix) {
if(!_photcut[ix])
_dipolewgt *= exactDipoleWeight(beta1,ombeta1,beta2,ombeta2,ix)/
_photonwgt[ix];
}
// calculate the weight for the photon removal
Energy2 s((_qnewdrf[0]+_qnewdrf[1]).m2());
// calculate the second part of the yfs form factor
// this is different for the different photon removal options
// option with no removal
if(_energyopt==0) {
_yfswgt *=
YFSFormFactors::exponentialYFSFF(beta1,ombeta1,beta2,ombeta2,
_qnewdrf[0].e(),_qnewdrf[1].e(),
_m[1],_m[2],s,_charge,_emin);
}
// weight for option with cut in the rest frame
else if(_energyopt==1) {
// yfs piece
double nbeta1(sqrt( (_qnewprf[0].e()+_m[1])*(_qnewprf[0].e()-_m[1]))
/_qnewprf[0].e());
double nbeta2(sqrt( (_qnewprf[1].e()+_m[2])*(_qnewprf[1].e()-_m[2]))
/_qnewprf[1].e());
double nomb1 (sqr(_m[1]/_qnewprf[0].e())/(1.+nbeta1));
double nomb2 (sqr(_m[2]/_qnewprf[1].e())/(1.+nbeta2));
_yfswgt *=
YFSFormFactors::exponentialYFSFF(nbeta1,nomb1,nbeta2,nomb2,
_qnewprf[0].e(),_qnewprf[1].e(),
_m[1],_m[2],s,_charge,_eminrest);
// dipole piece
// Find the momenta of the particles of original particles in new rest frame
Lorentz5Momentum pnew(_bigLdrf.x(),_bigLdrf.y(),
_bigLdrf.z(),_bigLdrf.e(),_m[0]);
pnew.rescaleEnergy();
SpinOneLorentzRotation boost(pnew.findBoostToCM());
Lorentz5Momentum q1=boost*_qdrf[0];
Lorentz5Momentum q2=boost*_qdrf[1];
// use this to calculate the form factor
nbeta1=sqrt( (q1.e()+_m[1])*(q1.e()-_m[1]))/q1.e();
nbeta2=sqrt( (q2.e()+_m[2])*(q2.e()-_m[2]))/q2.e();
nomb1 =sqr(_m[1]/q1.e())/(1.+nbeta1);
nomb2 =sqr(_m[2]/q2.e())/(1.+nbeta2);
_dipolewgt /=YFSFormFactors::exponentialYFSFF(nbeta1,nomb1,nbeta2,nomb2,
q1.e(),q2.e(),
_m[1],_m[2],_m[0]*_m[0],
_charge,_eminrest);
}
// weight for option with cut in the rest frame
else if(_energyopt==2) {
// yfs piece
double nbeta1(sqrt( (_qnewlab[0].e()+_m[1])*(_qnewlab[0].e()-_m[1]))
/_qnewlab[0].e());
double nbeta2(sqrt( (_qnewlab[1].e()+_m[2])*(_qnewlab[1].e()-_m[2]))
/_qnewlab[1].e());
double nomb1 (sqr(_m[1]/_qnewlab[0].e())/(1.+nbeta1));
double nomb2 (sqr(_m[2]/_qnewlab[1].e())/(1.+nbeta2));
_yfswgt *=
YFSFormFactors::exponentialYFSFF(nbeta1,nomb1,nbeta2,nomb2,
_qnewlab[0].e(),_qnewlab[1].e(),
_m[1],_m[2],s,_charge,_eminlab);
// dipole piece
// Find the momenta of the particles of original particles in new rest frame
Lorentz5Momentum pnew(_bigLdrf.x(),_bigLdrf.y(),
_bigLdrf.z(),_bigLdrf.e(),_m[0]);
pnew.rescaleEnergy();
SpinOneLorentzRotation boost(pnew.findBoostToCM());
Lorentz5Momentum q1=boost*_qdrf[0];
Lorentz5Momentum q2=boost*_qdrf[1];
// then boost to the lab
boost.setBoost(boostv);
q1 *=boost;
q2 *=boost;
// use this to calculate the form factor
nbeta1=sqrt( (q1.e()+_m[1])*(q1.e()-_m[1]))
/q1.e();
nbeta2=sqrt( (q2.e()+_m[2])*(q2.e()-_m[2]))
/q2.e();
nomb1 =sqr(_m[1]/q1.e())/(1.+nbeta1);
nomb2 =sqr(_m[2]/q2.e())/(1.+nbeta2);
_dipolewgt /=YFSFormFactors::exponentialYFSFF(nbeta1,nomb1,nbeta2,nomb2,
q1.e(),q2.e(),_m[1],_m[2],
_m[0]*_m[0],_charge,_eminlab);
}
// Calculating jacobian weight
_jacobianwgt = jacobianWeight();
// Calculate the weight for the corrections
_mewgt = meWeight(children);
}
// otherwise copy momenta
else {
for(unsigned int ix=0;ix<2;++ix) {
_qnewdrf[ix]=_qdrf[ix];
_qnewprf[ix]=_qprf[ix];
_qnewlab[ix]=_qlab[ix];
}
_jacobianwgt = 1.0;
_yfswgt*=YFSFormFactors::exponentialYFSFF(beta1,ombeta1,beta2,ombeta2,
_qdrf[0].e(),_qdrf[1].e(),
_m[1],_m[2],_m[0]*_m[0],
_charge,_emin);
_dipolewgt = 1.0;
}
double wgt;
if(_mode!=5) {
// virtual corrections
_mewgt += virtualWeight(children);
// calculate the weight depending on the option
if(_mode==0) wgt = _maxwgt;
else if(_mode==1) wgt = _mewgt*_yfswgt*_jacobianwgt*_dipolewgt;
else if(_mode==2) wgt = _jacobianwgt*_yfswgt*_dipolewgt;
else if(_mode==3) wgt = _yfswgt*_dipolewgt;
else wgt = _yfswgt;
}
// special to test NLO results
else {
double beta1 = sqrt((_qdrf[0].e()+_m[1])*(_qdrf[0].e()-_m[1]))/_qdrf[0].e();
double beta2 = sqrt((_qdrf[1].e()+_m[2])*(_qdrf[1].e()-_m[2]))/_qdrf[1].e();
double ombeta1 = sqr(_m[1]/_qdrf[0].e())/(1.+beta1);
double ombeta2 = sqr(_m[2]/_qdrf[1].e())/(1.+beta2);
double yfs = YFSFormFactors::YFSFF(beta1,ombeta1,beta2,ombeta2,
_qdrf[0].e(),_qdrf[1].e(),
_m[1],_m[2],_m[0]*_m[0],
_charge,_emin);
double nbar = YFSFormFactors::nbarFF(beta1,ombeta1,beta2,ombeta2,_charge,
_emax,_emin,_dipoleopt==1);
wgt = 1.+virtualWeight(children)+yfs+nbar*_dipolewgt*_mewgt*_jacobianwgt;
}
return wgt;
}
double FFDipole::photon(double beta1,double ombeta1,
double beta2,double ombeta2) {
// generate the polar angle
double r1,r2,costh,sinth,opbc,ombc;
// relative weights for the two terms
double Pp(log((1+beta2)/ombeta2));
double Pm(log((1+beta1)/ombeta1));
Pp/=(Pp+Pm);
// generate the angle
double wgt=1.;
do {
r1=UseRandom::rnd();
r2=UseRandom::rnd();
// 1/(1+bc) branch
if(r1<=Pp) {
opbc = pow(1.+beta2,r2)*pow(ombeta2,1.-r2);
costh = -1./beta2*(1.-opbc);
ombc = 1.-beta1*costh;
sinth = sqrt(opbc*(2.-opbc)-(1.+beta2)*ombeta2*sqr(costh));
}
// 1/(1-bc) branch
else {
ombc = pow(1.+beta1,1.-r2)*pow(ombeta1,r2);
costh = 1./beta1*(1.-ombc);
opbc = 1.+beta2*costh;
sinth = sqrt(ombc*(2.-ombc)-(1.+beta1)*ombeta1*sqr(costh));
}
// wgt for rejection
if(_dipoleopt==1)
wgt = 1.-0.5/(1.+beta1*beta2)*(ombeta1*(1.+beta1)*opbc/ombc+
ombeta2*(1.+beta2)*ombc/opbc);
}
while(UseRandom::rnd()>wgt);
// generate the polar angle randomly in -pi->+pi
double phi(-pi+UseRandom::rnd()*2.*pi);
// generate the ln(energy) uniformly in ln(_emin)->ln(_emax)
Energy en(pow(_emax/_emin,UseRandom::rnd())*_emin);
// calculate the weight (omit the pre and energy factors
// which would cancel later anyway)
if(_dipoleopt==0)
wgt = 0.5*(1.+beta1*beta2)/opbc/ombc;
else
wgt = 0.25*(2.*(1.+beta1*beta2)/opbc/ombc
-ombeta1*(1.+beta1)/sqr(ombc)
-ombeta2*(1.+beta2)/sqr(opbc));
// store the angles
_cosphot.push_back(costh);
_sinphot.push_back(sinth);
// store the four vector for the photon
_ldrf.push_back(Lorentz5Momentum(en*sinth*cos(phi),
en*sinth*sin(phi),
en*costh,en,
ZERO));
// add the photon momentum to the total
_bigLdrf+=_ldrf.back();
// return the weight
return wgt;
}
double FFDipole::meWeight(const ParticleVector & children) {
if(_multiplicity==0) return 1.;
// option which does nothing
if(_betaopt==0) {
return 1.;
}
// collinear approx
else if(_betaopt <= 3) {
return collinearWeight(children);
}
else if (_betaopt == 4 ) {
if(_decayer&&_decayer->hasRealEmissionME()) {
double outwgt=1.;
// values of beta etc to evaluate the dipole
double beta1(sqrt( (_qnewdrf[0].e()+_m[1])*(_qnewdrf[0].e()-_m[1]))/
_qnewdrf[0].e());
double beta2(sqrt( (_qnewdrf[1].e()+_m[2])*(_qnewdrf[1].e()-_m[2]))/
_qnewdrf[1].e());
double ombeta1(sqr(_m[1]/_qnewdrf[0].e())/(1.+beta1));
double ombeta2(sqr(_m[2]/_qnewdrf[1].e())/(1.+beta2));
// storage of the weights
ParticleVector ptemp;
for(unsigned int ix=0;ix<children.size();++ix)
ptemp.push_back(new_ptr(Particle(children[ix]->dataPtr())));
ptemp.push_back(new_ptr(Particle(getParticleData(ParticleID::gamma))));
for(unsigned int i=0;i<_multiplicity;++i) {
PPtr new_parent = new_ptr(Particle(*_parent));
if(_photcut[i]) continue;
// compute the angle terms
// if cos is greater than zero use result accurate as cos->1
double opbc,ombc;
if(_cosphot[i]>0) {
opbc=1.+beta2*_cosphot[i];
ombc=ombeta1+beta1*sqr(_sinphot[i])/(1.+_cosphot[i]);
}
// if cos is less than zero use result accurate as cos->-1
else {
opbc=ombeta2+beta2*sqr(_sinphot[i])/(1.-_cosphot[i]);
ombc=1.-beta1*_cosphot[i];
}
// dipole factor for denominator
double dipole = 2./opbc/ombc*(1.+beta1*beta2
-0.5*ombeta1*(1.+beta1)*opbc/ombc
-0.5*ombeta2*(1.+beta2)*ombc/opbc);
// energy and momentum of the photon
Energy L0(_ldrf[i].e()),modL(_ldrf[i].rho());
// 3-momenta of charged particles
Energy modq(_qdrf[0].rho());
// calculate the energy of the fermion pair
Energy newE12(-L0+sqrt(sqr(_m[0])+sqr(modL)));
// 3-momentum rescaling factor (NOT energy rescaling).
double kappa(Kinematics::pstarTwoBodyDecay(newE12,_m[1],_m[2])/modq);
// calculate the rescaled momenta
Lorentz5Momentum porig[3];
for(unsigned int ix=0;ix<2;++ix) {
porig[ix] = kappa*_qdrf[ix];
porig[ix].setMass(_m[ix+1]);
porig[ix].rescaleEnergy();
}
porig[2] = _ldrf[i];
// calculate the momentum of the decaying particle in dipole rest frame
Lorentz5Momentum pnew(_ldrf[i].x(),_ldrf[i].y(),
_ldrf[i].z(),_ldrf[i].e(),_m[0]);
pnew.rescaleEnergy();
// Find the momenta of the particles in the rest frame of the parent...
// First get the boost from the parent particle
Boost boost = pnew.findBoostToCM();
LorentzRotation rot1(-boost, pnew.e()/pnew.mass());
// check the photon energy
Lorentz5Momentum ptest = _ldrf[i];
ptest.boost(boost);
if(_energyopt==1&&ptest.e()<_eminrest) continue;
new_parent->transform(rot1);
// rotation to put the emitter along the z axis
// first particle emits
unsigned int iemit = _cosphot[i]>0. ? 0 : 1;
LorentzRotation rot2;
rot2.setRotateZ(-porig[iemit].phi());
rot2.rotateY(porig[iemit].theta());
rot2.rotateZ(porig[iemit].phi());
rot2.invert();
// Boost the momenta of the charged particles
for(unsigned int ix=0;ix<3;++ix) {
porig[ix].transform(rot2);
ptemp[ix]->set5Momentum(porig[ix]);
}
new_parent->transform(rot2);
if(_cosphot[i]>0.) {
outwgt -= _decayer->
realEmissionME(_decayer->imode(),*new_parent,ptemp,
0,_cosphot[i],_sinphot[i],rot1,rot2)/
(_charge/sqr(_ldrf[i].e())*dipole);
}
else {
outwgt -= _decayer->
realEmissionME(_decayer->imode(),*new_parent,ptemp,
1,-_cosphot[i],_sinphot[i],rot1,rot2)/
(_charge/sqr(_ldrf[i].e())*dipole);
}
rot1.invert();
rot2.invert();
new_parent->transform(rot2);
new_parent->transform(rot1);
}
return outwgt;
}
else
return collinearWeight(children);
}
return 1.;
}
double FFDipole::collinearWeight(const ParticleVector & children) {
double outwgt=1.;
// spins of the decay products
PDT::Spin spin1(children[0]->dataPtr()->iSpin());
PDT::Spin spin2(children[1]->dataPtr()->iSpin());
// values of beta etc to evaluate the dipole
double beta1(sqrt( (_qnewdrf[0].e()+_m[1])*(_qnewdrf[0].e()-_m[1]))/
_qnewdrf[0].e());
double beta2(sqrt( (_qnewdrf[1].e()+_m[2])*(_qnewdrf[1].e()-_m[2]))/
_qnewdrf[1].e());
double ombeta1(sqr(_m[1]/_qnewdrf[0].e())/(1.+beta1));
double ombeta2(sqr(_m[2]/_qnewdrf[1].e())/(1.+beta2));
// storage of the weights
double twgt,dipole;
double opbc,ombc;
// compute the collinear approx
for(unsigned int i=0;i<_multiplicity;++i) {
if(_photcut[i]) continue;
// compute the angle terms
// if cos is greater than zero use result accurate as cos->1
if(_cosphot[i]>0) {
opbc=1.+beta2*_cosphot[i];
ombc=ombeta1+beta1*sqr(_sinphot[i])/(1.+_cosphot[i]);
}
// if cos is less than zero use result accurate as cos->-1
else {
opbc=ombeta2+beta2*sqr(_sinphot[i])/(1.-_cosphot[i]);
ombc=1.-beta1*_cosphot[i];
}
// dipole factor for denominator
dipole = 2.*(1.+beta1*beta2
-0.5*ombeta1*(1.+beta1)*opbc/ombc
-0.5*ombeta2*(1.+beta2)*ombc/opbc);
twgt=0.;
// correction for the first particle
double ratio(_ldrf[i].e()/_qnewdrf[0].e());
if(spin1==PDT::Spin0) twgt += 0.;
else if(spin1==PDT::Spin1Half)
twgt += opbc*ratio/(1.+(1.+beta1*beta2)/ratio/opbc);
else
twgt += 2.*sqr(opbc*ratio) *
(+1./(1+beta1*beta2+_ldrf[i].e()/_qnewdrf[1].e()*ombc)
+(1.+beta1*beta2)/sqr(1.+beta1*beta2
+_ldrf[i].e()/_qnewdrf[0].e()*opbc));
// correction for the second particle
ratio =_ldrf[i].e()/_qnewdrf[1].e();
if(spin2==PDT::Spin0) twgt += 0.;
else if(spin2==PDT::Spin1Half)
twgt += ombc*ratio/(1.+(1.+beta1*beta2)/ratio/ombc);
else
twgt += 2.*sqr(ombc*ratio) *
(1./(1. + beta1*beta2 + _ldrf[i].e()/_qnewdrf[0].e()*opbc)
+ (1.+beta1*beta2) / sqr(1. + beta1*beta2
+ _ldrf[i].e()/_qnewdrf[1].e()*ombc));
twgt/=dipole;
outwgt+=twgt;
}
return outwgt;
}
bool FFDipole::boostMomenta(const Boost & boostv) {
// total energy and momentum of photons
Energy L0(_bigLdrf.e()),modL(_bigLdrf.rho());
// 3-momenta of charged particles
Energy modq(_qdrf[0].rho());
// calculate the energy of the fermion pair
Energy newE12(-L0+sqrt(_m[0]*_m[0]+modL*modL));
// check this is allowed
if(newE12<_m[1]+_m[2]){return false;}
// 3-momentum rescaling factor (NOT energy rescaling).
double kappa(Kinematics::pstarTwoBodyDecay(newE12,_m[1],_m[2])/modq);
// calculate the rescaled momenta
for(unsigned int ix=0;ix<2;++ix) {
_qnewdrf[ix] = kappa*_qdrf[ix];
_qnewdrf[ix].setMass(_m[ix+1]);
_qnewdrf[ix].rescaleEnergy();
}
// calculate the momentum of the decaying particle in dipole rest frame
Lorentz5Momentum pnew(_bigLdrf.x(),_bigLdrf.y(),
_bigLdrf.z(),_bigLdrf.e(),_m[0]);
pnew.rescaleEnergy();
// Find the momenta of the particles in the rest frame
// of the parent...
// First get the boost from the parent particle
SpinOneLorentzRotation boost(pnew.findBoostToCM());
// Boost the momenta of the charged particles
for(unsigned int ix=0;ix<2;++ix) _qnewprf[ix]=boost*_qnewdrf[ix];
// Boost the total photon momentum
_bigLprf=boost*_bigLdrf;
// Boost the individual photon momenta
for(unsigned int ix=0;ix<_multiplicity;++ix){_lprf[ix]=boost*_ldrf[ix];}
// Now boost from the parent rest frame to the lab frame
boost.setBoost(boostv);
// Boosting charged particles
for(unsigned int ix=0;ix<2;++ix){_qnewlab[ix]=boost*_qnewprf[ix];}
// Boosting total photon momentum
_bigLlab=boost*_bigLprf;
// Boosting individual photon momenta
for(unsigned int ix=0;ix<_multiplicity;++ix){_llab[ix]=boost*_lprf[ix];}
return true;
}
unsigned int FFDipole::removePhotons() {
unsigned int nremoved(0);
// apply the cut in the rest frame
if(_energyopt==1) {
for(unsigned int ix=0;ix<_multiplicity;++ix) {
if(_lprf[ix].e()<_eminrest) {
++nremoved;
_photcut[ix]=true;
_bigLdrf-=_ldrf[ix];
_ldrf[ix]=Lorentz5Momentum();
}
}
}
// apply the cut in the lab frame
else if(_energyopt==2) {
for(unsigned int ix=0;ix<_multiplicity;++ix) {
if(_llab[ix].e()<_eminlab) {
++nremoved;
_photcut[ix]=true;
_bigLdrf-=_ldrf[ix];
_ldrf[ix]=Lorentz5Momentum();
}
}
}
// correction factor for dipoles if needed
if(_dipoleopt==0&&nremoved!=0) {
// calculate the velocities of the charged particles (crude/overvalued)
double beta1(sqrt((_qdrf[0].e()+_m[1])*(_qdrf[0].e()-_m[1]))/_qdrf[0].e());
double beta2(sqrt((_qdrf[1].e()+_m[2])*(_qdrf[1].e()-_m[2]))/_qdrf[1].e());
// calculate 1-beta to avoid numerical problems
double ombeta1(sqr(_m[1]/_qdrf[0].e())/(1.+beta1));
double ombeta2(sqr(_m[2]/_qdrf[1].e())/(1.+beta2));
// calculate the weights
for(unsigned int ix=0;ix<_multiplicity;++ix) {
if(_photcut[ix]) _dipolewgt *=
exactDipoleWeight(beta1,ombeta1,beta2,ombeta2,ix)/_photonwgt[ix];
}
}
// return number of remove photons
return nremoved;
}
double FFDipole::virtualWeight(const ParticleVector & children) {
double output = 0.;
// Virtual corrections for beta_0:
// These should be zero for the scalar case as there is no
// collinear singularity going by the dipoles above...
// Use mass of decaying particle...
if(_betaopt==2) {
if((children[0]->dataPtr()->iSpin())==2&&
(children[1]->dataPtr()->iSpin())==2
) {
output += (1.0*YFSFormFactors::_alpha/pi)
* log(sqr(_m[0]/_m[1]));
}
}
// OR Use invariant mass of final state children...
else if(_betaopt==3) {
if((children[0]->dataPtr()->iSpin())==2&&
(children[1]->dataPtr()->iSpin())==2
) {
output += (1.0*YFSFormFactors::_alpha/pi)
* log((_qnewprf[0]+_qnewprf[1]).m2()/sqr(_m[1]));
}
}
else if (_betaopt==4) {
if(_decayer&&_decayer->hasOneLoopME()) {
output +=
_decayer->oneLoopVirtualME(_decayer->imode(),*_parent,
children);
}
else {
output += (1.0*YFSFormFactors::_alpha/pi)
* log(sqr(_m[0]/_m[1]));
}
}
return output;
}
void FFDipole::dofinish() {
Interfaced::dofinish();
if(_weightOutput) {
_wgtsum /= double(_nweight);
_wgtsq /= double(_nweight);
_wgtsq = max(_wgtsq - sqr(_wgtsum),0.);
_wgtsq /= double(_nweight);
_wgtsq = sqrt(_wgtsq);
generator()->log() << "The average weight for QED Radiation in " << fullName()
<< " was " << _wgtsum << " +/- " << _wgtsq << '\n';
}
}
diff --git a/Decay/Radiation/FFDipole.h b/Decay/Radiation/FFDipole.h
--- a/Decay/Radiation/FFDipole.h
+++ b/Decay/Radiation/FFDipole.h
@@ -1,466 +1,461 @@
// -*- C++ -*-
//
// FFDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFDipole_H
#define HERWIG_FFDipole_H
//
// This is the declaration of the FFDipole class.
//
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Decay/DecayIntegrator.fh"
#include "Herwig/Utilities/Kinematics.h"
#include "Herwig/Utilities/Maths.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Vectors/Lorentz5Vector.h"
#include "ThePEG/Interface/Interfaced.h"
#include "FFDipole.fh"
namespace Herwig {
using namespace ThePEG;
using ThePEG::Constants::pi;
/** \ingroup Decay
*
* The FFDipole class generates radiation from a final-final dipole for
* the generation of photons in decay by the SOPTHY algorithm.
*
* @see SOPTHY
* @see \ref FFDipoleInterfaces "The interfaces"
* defined for FFDipole.
*/
class FFDipole: public Interfaced {
public:
/**
* The default constructor.
*/
FFDipole() :
_emin(1.e-6*MeV), _eminrest(100*MeV), _eminlab(100*MeV), _emax(),
_multiplicity(), _m(3), _charge(), _qdrf(2),
_qnewdrf(2), _qprf(2), _qnewprf(2), _qlab(2), _qnewlab(2), _dipolewgt(),
_yfswgt(), _jacobianwgt(), _mewgt(), _maxwgt(7.0), _mode(1), _maxtry(500),
_energyopt(1), _betaopt(4), _dipoleopt(), _nweight(0), _wgtsum(0.), _wgtsq(0.),
_weightOutput(false) {}
- /**
- * Destructor
- */
- virtual ~FFDipole();
-
public:
/**
* Member to generate the photons from the dipole
* @param p The decaying particle
* @param children The decay products
* @param decayer The decayer for this mode
* @return The decay products with additional radiation
*/
virtual ParticleVector generatePhotons(const Particle & p,
ParticleVector children,
tDecayIntegratorPtr decayer);
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 {return new_ptr(*this);}
/** 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 {return new_ptr(*this);}
//@}
protected:
/**
* Generate the momentum of a photon
* @param beta1 The velocity, \f$\beta_1\f$, of the first charged particle
* @param ombeta1 One minus the velocity, \f$1-\beta_1\f$, of the first
* charged particle which is supplied for numerical stability
* @param beta2 The velocity, \f$\beta_2\f$, of the second charged particle
* @param ombeta2 One minus the velocity, \f$1-\beta_2\f$, of the
* second charged particle which is supplied for numerical stability
* @return The contribution to the dipole weight
*/
double photon(double beta1,double ombeta1, double beta2, double ombeta2);
/**
* Calculate the exact weight for the dipole.
* @param beta1 Velocity of the first charged particle, \f$\beta_1\f$
* @param beta2 Velocity of the second charged particle, \f$\beta_2\f$.
* @param ombeta1 One minus the velocity of the first particle, \f$1-\beta_1\f$
* @param ombeta2 One minus the velocity of the second particle, \f$1-\beta_2\f$
* @param iphot The number of the photon for which the weight is required
* @return The weight
*/
double exactDipoleWeight(double beta1,double ombeta1,
double beta2,double ombeta2,unsigned int iphot) {
double opbc,ombc;
// if cos is greater than zero use result accurate as cos->1
if(_cosphot[iphot]>0) {
opbc=1.+beta2*_cosphot[iphot];
ombc=ombeta1+beta1*sqr(_sinphot[iphot])/(1.+_cosphot[iphot]);
}
// if cos is less than zero use result accurate as cos->-1
else {
opbc=ombeta2+beta2*sqr(_sinphot[iphot])/(1.-_cosphot[iphot]);
ombc=1.-beta1*_cosphot[iphot];
}
return 0.5/(opbc*ombc)*(1.+beta1*beta2
-0.5*ombeta1*(1.+beta1)*opbc/ombc
-0.5*ombeta2*(1.+beta2)*ombc/opbc);
}
/**
* Jacobian factor for the weight
*/
double jacobianWeight() {
Energy pcm1=Kinematics::pstarTwoBodyDecay(_m[0],_m[1],_m[2]);
Energy m12 =sqrt((_qnewdrf[0]+_qnewdrf[1]).m2()) ;
Energy pcm2=Kinematics::pstarTwoBodyDecay(m12,_m[1],_m[2]) ;
double betaprobeta = pcm2*_m[0]/pcm1/m12 ;
double spros = sqr(m12/_m[0]) ;
double deltafn = m12/(m12+_bigLdrf.e());
return betaprobeta*spros*deltafn ;
}
/**
* Matrix element weight
*/
double meWeight(const ParticleVector & children);
/**
* Member which generates the photons
* @param boost Boost vector to take the particles produced back from
* the decaying particle's rest frame to the lab
* @param children The decay products
*/
double makePhotons(const Boost & boost,
const ParticleVector & children);
/**
* Boost all the momenta from the dipole rest frame via the parent rest frame
* to the lab
* @param boost The boost vector from the rest frame to the lab
* @return Whether or not it suceeded
*/
bool boostMomenta(const Boost & boost);
/**
* Remove any photons which fail the energy cuts
* @return Number of photons removed
*/
unsigned int removePhotons();
/**
* The real emission weight in the collinear limit
*/
double collinearWeight(const ParticleVector & children);
/**
* The vrtiual correction weight
*/
double virtualWeight(const ParticleVector & children);
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* 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 assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFDipole & operator=(const FFDipole &) = delete;
private:
/**
* Debug output
**/
void printDebugInfo(const Particle & p,
const ParticleVector & children,
double wgt) const;
private:
/**
* The minimum photon energy in the boosted frame
*/
Energy _emin;
/**
* The minimum photon energy in the rest frame
*/
Energy _eminrest;
/**
* The minimum photon energy in the lab frame
*/
Energy _eminlab;
/**
* The maximum photon energy
*/
Energy _emax;
/**
* Photon multiplicity being generated
*/
unsigned int _multiplicity;
/**
* Masses of the particles involved
*/
vector<Energy> _m;
/**
* Produce of the particles charges
*/
double _charge;
/**
* Momenta of the particles in the dipole rest frame
*/
//@{
/**
* Momenta of the charged particles in the dipole rest frame before radiation
*/
vector<Lorentz5Momentum> _qdrf;
/** * Momenta of the charged particles in the dipole rest frame after radiation
*/
vector<Lorentz5Momentum> _qnewdrf;
/**
* Momenta of the photons in the dipole rest frame
*/
vector<Lorentz5Momentum> _ldrf;
/**
* Total momentum of the photons in the dipole rest frame
*/
Lorentz5Momentum _bigLdrf;
//@}
/**
* Momentum of the particles in the parent's rest frame
*/
//@{
/**
* Momenta of the charged particles in the parent's rest frame before radiation
*/
vector<Lorentz5Momentum> _qprf;
/**
* Momenta of the charged particles in the parent's rest frame after radiation
*/
vector<Lorentz5Momentum> _qnewprf;
/**
* Momenta of the photons in the parent rest frame
*/
vector<Lorentz5Momentum> _lprf;
/**
* Total momentum of the photons in the parent rest frame
*/
Lorentz5Momentum _bigLprf;
//@}
/**
* Momentum of the particles in the lab frame
*/
//@{
/**
* Momenta of the charged particles in the lab frame before radiation
*/
vector<Lorentz5Momentum> _qlab;
/**
* Momenta of the charged particles in the lab frame after radiation
*/
vector<Lorentz5Momentum> _qnewlab;
/**
* Momenta of the photons in the lab frame
*/
vector<Lorentz5Momentum> _llab;
/**
* Total momentum of the photons in the lab frame
*/
Lorentz5Momentum _bigLlab;
//@}
/**
* Reweighting factors due to differences between the true and crude
* distributions
*/
//@{
/**
* Reweighting factor for the real emission
*/
double _dipolewgt;
/**
* Reweighting factor for the YFS form-factor
*/
double _yfswgt;
/**
* Reweighting factor due to phase space
*/
double _jacobianwgt;
/**
* Reweighting factor due to matrix element corrections
*/
double _mewgt;
/**
* Maximum weight
*/
double _maxwgt;
//@}
/**
* Angles of the photons with respect to the first charged particle
* which are stored for numerical accuracy
*/
//@{
/**
* Cosine of the photon angles
*/
vector<double> _cosphot;
/**
* Sine of the photon angles
*/
vector<double> _sinphot;
//@}
/**
* Weights for the individual photons
*/
vector<double> _photonwgt;
/**
* Whether a given photon passes the energy cut
*/
vector<bool> _photcut;
/**
* Type of unweighting to perform
*/
unsigned int _mode;
/**
* Maximum number of attempts to generate a result
*/
unsigned int _maxtry;
/**
* Option for the energy cut-off
*/
unsigned int _energyopt;
/**
* Option for the inclusion of higher order corrections
*/
unsigned int _betaopt;
/**
* Option for the form of the primary distribution
*/
unsigned int _dipoleopt;
/**
* The decayer
*/
tDecayIntegratorPtr _decayer;
/**
* The decaying particle
*/
tPPtr _parent;
/**
* Storage of averages etc for testing
*/
//@{
/**
* Number of attempts
*/
unsigned int _nweight;
/**
* Sum of weights
*/
double _wgtsum;
/**
* Sum of squares of weights
*/
double _wgtsq;
/**
* Whether or not to output the averages
*/
bool _weightOutput;
//@}
};
}
#endif /* HERWIG_FFDipole_H */
diff --git a/Decay/TensorMeson/TensorMesonSpin3VectorDecayer.cc b/Decay/TensorMeson/TensorMesonSpin3VectorDecayer.cc
--- a/Decay/TensorMeson/TensorMesonSpin3VectorDecayer.cc
+++ b/Decay/TensorMeson/TensorMesonSpin3VectorDecayer.cc
@@ -1,285 +1,285 @@
// -*- C++ -*-
//
// Spin3MesonTensorPScalarDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 TensorMesonSpin3VectorDecayer class.
//
#include "TensorMesonSpin3VectorDecayer.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Helicity/WaveFunction/Rank3TensorWaveFunction.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/DecayMode.h"
#include "Herwig/Decay/GeneralDecayMatrixElement.h"
using namespace Herwig;
using namespace ThePEG::Helicity;
void TensorMesonSpin3VectorDecayer::doinitrun() {
DecayIntegrator::doinitrun();
if(initialize()) {
for(unsigned int ix=0;ix<incoming_.size();++ix)
if(mode(ix)) maxWeight_[ix] = mode(ix)->maxWeight();
}
}
void TensorMesonSpin3VectorDecayer::doinit() {
DecayIntegrator::doinit();
// check consistence of the parameters
unsigned int isize=incoming_.size();
if(isize!=outgoing_.size()||isize!=maxWeight_.size()||isize!=coupling_.size())
throw InitException() << "Inconsistent parameters TensorMesonSpin3VectorDecayer"
<< Exception::abortnow;
// set up the integration channels
vector<double> wgt(0);
PhaseSpaceModePtr mode;
for(unsigned int ix=0;ix<incoming_.size();++ix) {
tPDPtr in = getParticleData(incoming_[ix]);
tPDVector out = {getParticleData(outgoing_[ix].first),
getParticleData(outgoing_[ix].second)};
if(in&&out[0]&&out[1])
mode=new_ptr(PhaseSpaceMode(in,out,maxWeight_[ix]));
else
mode=PhaseSpaceModePtr();
addMode(mode);
}
}
int TensorMesonSpin3VectorDecayer::modeNumber(bool & cc,tcPDPtr parent,
const tPDVector & children) const {
if(children.size()!=2) return -1;
int id(parent->id());
int idbar = parent->CC() ? parent->CC()->id() : id;
int id1(children[0]->id());
int id1bar = children[0]->CC() ? children[0]->CC()->id() : id1;
int id2(children[1]->id());
int id2bar = children[1]->CC() ? children[1]->CC()->id() : id2;
int imode(-1);
unsigned int ix(0);
cc=false;
do {
if(id ==incoming_[ix]) {
if((id1 ==outgoing_[ix].first&&id2 ==outgoing_[ix].second)||
(id2 ==outgoing_[ix].first&&id1 ==outgoing_[ix].second)) imode=ix;
}
if(idbar==incoming_[ix]) {
if((id1bar==outgoing_[ix].first&&id2bar==outgoing_[ix].second)||
(id2bar==outgoing_[ix].first&&id1bar==outgoing_[ix].second)) {
imode=ix;
cc=true;
}
}
++ix;
}
while(ix<incoming_.size()&&imode<0);
return imode;
}
void TensorMesonSpin3VectorDecayer::persistentOutput(PersistentOStream & os) const {
os << incoming_ << outgoing_ << maxWeight_ << ounit(coupling_,GeV);
}
void TensorMesonSpin3VectorDecayer::persistentInput(PersistentIStream & is, int) {
is >> incoming_ >> outgoing_ >> maxWeight_ >> iunit(coupling_,GeV);
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<TensorMesonSpin3VectorDecayer,DecayIntegrator>
describeHerwigTensorMesonSpin3VectorDecayer("Herwig::TensorMesonSpin3VectorDecayer", "HwTMDecay.so");
void TensorMesonSpin3VectorDecayer::Init() {
static ClassDocumentation<TensorMesonSpin3VectorDecayer> documentation
("The TensorMesonSpin3VectorDecayer class is designed for the decay"
" of a tensor meson to a tensor and pseudoscalar mesons.");
static Command<TensorMesonSpin3VectorDecayer> interfaceSetUpDecayMode
("SetUpDecayMode",
"Set up the particles, coupling(GeV) and max weight for a decay",
&TensorMesonSpin3VectorDecayer::setUpDecayMode, false);
}
string TensorMesonSpin3VectorDecayer::setUpDecayMode(string arg) {
// parse first bit of the string
string stype = StringUtils::car(arg);
arg = StringUtils::cdr(arg);
// extract PDG code for the incoming particle
long in = stoi(stype);
tcPDPtr pData = getParticleData(in);
if(!pData)
return "Incoming particle with id " + std::to_string(in) + "does not exist";
if(pData->iSpin()!=PDT::Spin2)
return "Incoming particle with id " + std::to_string(in) + "does not have spin 2";
// and outgoing particles
stype = StringUtils::car(arg);
arg = StringUtils::cdr(arg);
pair<long,long> out;
out.first = stoi(stype);
pData = getParticleData(out.first);
if(!pData)
return "First outgoing particle with id " + std::to_string(out.first) + "does not exist";
if(pData->iSpin()!=PDT::Spin3)
return "First outgoing particle with id " + std::to_string(out.first) + "does not have spin 3";
out.first = stoi(stype);
stype = StringUtils::car(arg);
arg = StringUtils::cdr(arg);
out.second = stoi(stype);
pData = getParticleData(out.second);
if(!pData)
return "Second outgoing particle with id " + std::to_string(out.second) + "does not exist";
if(pData->iSpin()!=PDT::Spin1)
return "Second outgoing particle with id " + std::to_string(out.second) + "does not have spin 1";
// get the coupling
stype = StringUtils::car(arg);
arg = StringUtils::cdr(arg);
Energy g = stof(stype)*GeV;
// and the maximum weight
stype = StringUtils::car(arg);
arg = StringUtils::cdr(arg);
double wgt = stof(stype);
// store the information
incoming_.push_back(in);
outgoing_.push_back(out);
coupling_.push_back(g);
maxWeight_.push_back(wgt);
// success
return "";
}
void TensorMesonSpin3VectorDecayer::
constructSpinInfo(const Particle & part, ParticleVector decay) const {
TensorWaveFunction::constructSpinInfo(tensors_,const_ptr_cast<tPPtr>(&part),
incoming,true,false);
// set up the spin information for the decay products
Rank3TensorWaveFunction::constructSpinInfo(rank3_,decay[0],
outgoing,true,false);
VectorWaveFunction::constructSpinInfo(vectors_,decay[1],outgoing,true,
decay[1]->id()==ParticleID::gamma);
}
// matrix elememt for the process
double TensorMesonSpin3VectorDecayer::me2(const int,const Particle & part,
const tPDVector & outgoing,
const vector<Lorentz5Momentum> & momenta,
MEOption meopt) const {
if(!ME())
ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin2,PDT::Spin3,PDT::Spin1)));
// check for photons
bool photon(outgoing[1]->id()==ParticleID::gamma);
// stuff for incoming particle
if(meopt==Initialize) {
rho_ = RhoDMatrix(PDT::Spin2);
TensorWaveFunction::
calculateWaveFunctions(tensors_,rho_,const_ptr_cast<tPPtr>(&part),
incoming,false);
}
rank3_.resize(7);
Rank3TensorWaveFunction twave(momenta[0],outgoing[0],Helicity::outgoing);
for(unsigned int ihel=0;ihel<7;++ihel) {
twave.reset(ihel);
rank3_[ihel] = twave.wave();
}
vectors_.resize(3);
for(unsigned int ix=0;ix<3;++ix) {
if(photon && ix==1) continue;
vectors_[ix] = HelicityFunctions::polarizationVector(-momenta[1],ix,Helicity::outgoing);
}
// calculate the matrix element
Energy2 denom[2] = {part.momentum()*momenta[0]-part.mass() *momenta[0].mass(),
momenta[0] *momenta[1]-momenta[0].mass()*momenta[1].mass()};
double fact(coupling_[imode()]/part.mass());
for(unsigned int ih1=0;ih1<7;++ih1) {
for(unsigned int ih2=0;ih2<3;++ih2) {
if(ih2==1 && photon) {
for(unsigned int ih0=0;ih0<5;++ih0) (*ME())(ih0,ih1,ih2)=0.;
}
else {
LorentzPolarizationVector v0 = vectors_[ih2] - momenta[1]*momenta[0].dot(vectors_[ih2])/denom[1];
LorentzTensor<double> t0 = rank3_[ih1].dot(v0,0);
LorentzPolarizationVectorE v1 = t0.postDot(momenta[1]);
Complex d1 = v1*momenta[1]/denom[0];
for(unsigned int ih0=0;ih0<5;++ih0) {
LorentzPolarizationVectorE v2 = tensors_[ih0].postDot(momenta[0]);
Complex d2 = v2*momenta[0]/denom[0];
(*ME())(ih0,ih1,ih2) = fact*(t0*tensors_[ih0] - 2.*v1.dot(v2)/denom[0]+d1*d2);
}
}
}
}
double output = ME()->contract(rho_).real();
// test of the answer
- double test = 7./5.*sqr(fact);
- if(photon) test *=2./3.;
+ // double test = 7./5.*sqr(fact);
+ // if(photon) test *=2./3.;
// cout << "testing matrix element for " << part.PDGName() << " -> "
// << outgoing[0]->PDGName() << " " << outgoing[1]->PDGName() << " "
// << output << " " << test << " " << (output-test)/(output+test) << endl;
// return the answer
return output;
}
bool TensorMesonSpin3VectorDecayer::twoBodyMEcode(const DecayMode & dm,int & mecode,
double & coupling) const {
int imode(-1);
int id(dm.parent()->id());
int idbar = dm.parent()->CC() ? dm.parent()->CC()->id() : id;
ParticleMSet::const_iterator pit(dm.products().begin());
int id1((**pit).id());
int id1bar = (**pit).CC() ? (**pit).CC()->id() : id1;
++pit;
int id2((**pit).id());
int id2bar = (**pit).CC() ? (**pit).CC()->id() : id2;
unsigned int ix(0); bool order(false);
do {
if(id ==incoming_[ix]) {
if(id1==outgoing_[ix].first&&id2==outgoing_[ix].second) {
imode=ix;
order=true;
}
if(id2==outgoing_[ix].first&&id1==outgoing_[ix].second) {
imode=ix;
order=false;
}
}
if(idbar==incoming_[ix]&&imode<0) {
if(id1bar==outgoing_[ix].first&&id2bar==outgoing_[ix].second) {
imode=ix;
order=true;
}
if(id2bar==outgoing_[ix].first&&id1bar==outgoing_[ix].second) {
imode=ix;
order=false;
}
}
++ix;
}
while(ix<incoming_.size()&&imode<0);
coupling=coupling_[imode]/dm.parent()->mass();
mecode=22;
return order;
}
void TensorMesonSpin3VectorDecayer::dataBaseOutput(ofstream & output,
bool header) const {
if(header) output << "update decayers set parameters=\"";
// parameters for the DecayIntegrator base class
DecayIntegrator::dataBaseOutput(output,false);
// the rest of the parameters
for(unsigned int ix=0;ix<incoming_.size();++ix) {
output << "do " << name() << ":SetUpDecayMode " << incoming_[ix] << " "
<< outgoing_[ix].first << " " << outgoing_[ix].second << " "
<< coupling_[ix]/GeV << " " << maxWeight_[ix] << "\n";
}
if(header) output << "\n\" where BINARY ThePEGName=\""
<< fullName() << "\";" << endl;
}
diff --git a/Decay/WeakCurrents/WeakBaryonCurrent.cc b/Decay/WeakCurrents/WeakBaryonCurrent.cc
--- a/Decay/WeakCurrents/WeakBaryonCurrent.cc
+++ b/Decay/WeakCurrents/WeakBaryonCurrent.cc
@@ -1,202 +1,202 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the WeakBaryonCurrent class.
//
#include "WeakBaryonCurrent.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
#include "ThePEG/Helicity/HelicityFunctions.h"
using namespace Herwig;
WeakBaryonCurrent::WeakBaryonCurrent() {}
IBPtr WeakBaryonCurrent::clone() const {
return new_ptr(*this);
}
IBPtr WeakBaryonCurrent::fullclone() const {
return new_ptr(*this);
}
void WeakBaryonCurrent::persistentOutput(PersistentOStream & os) const {
os << formFactor_;
}
void WeakBaryonCurrent::persistentInput(PersistentIStream & is, int) {
is >> formFactor_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<WeakBaryonCurrent,WeakCurrent>
describeHerwigWeakBaryonCurrent("Herwig::WeakBaryonCurrent", "Herwig.so");
void WeakBaryonCurrent::Init() {
static ClassDocumentation<WeakBaryonCurrent> documentation
("The WeakBaryonCurrent class is a wrapper for the BaryonFormFactor"
" so it can be used as a WeakCurrent");
static Reference<WeakBaryonCurrent,BaryonFormFactor> interfaceFormFactor
("FormFactor",
"The baryon form factor",
&WeakBaryonCurrent::formFactor_, false, false, true, false, false);
}
void WeakBaryonCurrent::doinit() {
// initialize the form factor
formFactor_->init();
// set the modes
for(unsigned int iloc=0;iloc<formFactor_->numberOfFactors();++iloc) {
int ispin(0), ospin(0), spect1(0), spect2(0), inquark(0), outquark(0);
formFactor_->formFactorInfo(iloc,ispin,ospin,spect1,spect2,inquark,outquark);
addDecayMode(outquark,-inquark);
}
setInitialModes(formFactor_->numberOfFactors());
WeakCurrent::doinit();
}
// complete the construction of the decay mode for integration
bool WeakBaryonCurrent::createMode(int icharge, tcPDPtr ,
- FlavourInfo flavour,
+ FlavourInfo ,
unsigned int imode,PhaseSpaceModePtr mode,
unsigned int iloc,int ires,
PhaseSpaceChannel phase, Energy upp ) {
unsigned int iq(0),ia(0);
tPDVector out = particles(icharge,imode,iq,ia);
// make sure the the decays are kinematically allowed
Energy min =out[0]->massMin()+out[1]->massMin();
if(min>=upp) return false;
// set the resonances and check charge
tPDPtr res;
if(icharge==3) res=getParticleData(ParticleID::Wplus );
else if(icharge==-3) res=getParticleData(ParticleID::Wminus);
else res=getParticleData(ParticleID::gamma );
// create the channel
mode->addChannel((PhaseSpaceChannel(phase),ires,res,ires+1,iloc+1,ires+1,iloc+2));
// return if successful
return true;
}
// the particles produced by the current
tPDVector WeakBaryonCurrent::particles(int icharge, unsigned int imode, int , int ) {
tPDVector extpart(2);
int id0(0),id1(0);
formFactor_->particleID(imode,id0,id1);
extpart[0] = getParticleData(id0);
if(extpart[0]->CC()) extpart[0]=extpart[0]->CC();
extpart[1] = getParticleData(id1);
int charge = extpart[0]->iCharge()+extpart[1]->iCharge();
if(charge==icharge)
return extpart;
else if(charge==-icharge) {
for(unsigned int ix=0;ix<2;++ix)
if(extpart[ix]->CC()) extpart[ix]=extpart[ix]->CC();
return extpart;
}
else
return tPDVector();
}
void WeakBaryonCurrent::constructSpinInfo(ParticleVector decay) const {
if(decay[0]->id()>0) {
SpinorWaveFunction ::constructSpinInfo(wave_ ,decay[1],outgoing,true);
SpinorBarWaveFunction::constructSpinInfo(wavebar_,decay[0],outgoing,true);
}
else {
SpinorWaveFunction ::constructSpinInfo( wave_,decay[0],outgoing,true);
SpinorBarWaveFunction::constructSpinInfo(wavebar_,decay[1],outgoing,true);
}
}
// hadronic current
vector<LorentzPolarizationVectorE>
WeakBaryonCurrent::current(tcPDPtr ,
FlavourInfo flavour,
const int, const int, Energy & scale,
const tPDVector & outgoing,
const vector<Lorentz5Momentum> & momenta,
DecayIntegrator::MEOption) const {
useMe();
Lorentz5Momentum q = momenta[0]+momenta[1];
q.rescaleMass();
scale=q.mass();
int in = abs(outgoing[0]->id());
int out = abs(outgoing[1]->id());
Energy m1 = outgoing[0]->mass();
Energy m2 = outgoing[1]->mass();
bool cc = false;
unsigned int imode = formFactor_->formFactorNumber(in,out,cc);
// todo generalize to spin != 1/2
assert(outgoing[0]->iSpin()==PDT::Spin1Half &&
outgoing[1]->iSpin()==PDT::Spin1Half );
wave_.resize(2);
wavebar_.resize(2);
for(unsigned int ix=0;ix<2;++ix) {
wavebar_[ix] = HelicityFunctions::dimensionedSpinorBar(-momenta[0],ix,Helicity::outgoing);
wave_[ix] = HelicityFunctions::dimensionedSpinor (-momenta[1],ix,Helicity::outgoing);
}
// get the form factors
Complex f1v(0.),f2v(0.),f3v(0.),f1a(0.),f2a(0.),f3a(0.);
formFactor_->SpinHalfSpinHalfFormFactor(sqr(scale),imode,in,out,m1,m2,
f1v,f2v,f3v,f1a,f2a,f3a,flavour,
BaryonFormFactor::TimeLike);
Complex left = f1v - f1a + f2v -double((m1-m2)/(m1+m2))*f2a;
Complex right = f1v + f1a + f2v +double((m1-m2)/(m1+m2))*f2a;
vector<LorentzPolarizationVectorE> baryon;
Lorentz5Momentum diff = momenta[0]-momenta[1];
for(unsigned int ohel1=0;ohel1<2;++ohel1) {
for(unsigned int ohel2=0;ohel2<2;++ohel2) {
LorentzPolarizationVectorE
vtemp = wave_[ohel2].generalCurrent(wavebar_[ohel1],left,right);
complex<Energy> vspin=wave_[ohel2].scalar (wavebar_[ohel1]);
complex<Energy> aspin=wave_[ohel2].pseudoScalar(wavebar_[ohel1]);
vtemp-= (f2v*vspin+f2a*aspin)/(m1+m2)*diff;
vtemp+= (f3v*vspin+f3a*aspin)/(m1+m2)*q;
baryon.push_back(vtemp);
}
}
// return the answer
return baryon;
}
bool WeakBaryonCurrent::accept(vector<int> id) {
assert(id.size()==2);
int itemp[2] = {id[0],id[1]};
for(unsigned int ix=0;ix<2;++ix)
if(itemp[ix]<0) itemp[ix]=-itemp[ix];
bool cc = false;
return formFactor_->formFactorNumber(itemp[0],itemp[1],cc)>=0;
}
// the decay mode
unsigned int WeakBaryonCurrent::decayMode(vector<int> idout) {
assert(idout.size()==2);
int itemp[2] = {idout[0],idout[1]};
for(unsigned int ix=0;ix<2;++ix)
if(itemp[ix]<0) itemp[ix]=-itemp[ix];
bool cc = false;
return formFactor_->formFactorNumber(itemp[0],itemp[1],cc);
}
// output the information for the database
void WeakBaryonCurrent::dataBaseOutput(ofstream & output,bool header,
bool create) const {
if(header) output << "update decayers set parameters=\"";
if(create) output << "create Herwig::WeakBaryonCurrent " << name() << "\n";
output << "newdef " << name() << ":FormFactor " << formFactor_ << "\n";
WeakCurrent::dataBaseOutput(output,false,false);
if(header) output << "\n\" where BINARY ThePEGName=\"" << fullName() << "\";" << endl;
}
diff --git a/Hadronization/GluonMassGenerator.cc b/Hadronization/GluonMassGenerator.cc
--- a/Hadronization/GluonMassGenerator.cc
+++ b/Hadronization/GluonMassGenerator.cc
@@ -1,63 +1,59 @@
// -*- C++ -*-
//
// GluonMassGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 GluonMassGenerator class.
//
#include "GluonMassGenerator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ClusterHadronizationHandler.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-GluonMassGenerator::GluonMassGenerator() {}
-
-GluonMassGenerator::~GluonMassGenerator() {}
-
IBPtr GluonMassGenerator::clone() const {
return new_ptr(*this);
}
IBPtr GluonMassGenerator::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void GluonMassGenerator::persistentOutput(PersistentOStream &) const {}
void GluonMassGenerator::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<GluonMassGenerator,HandlerBase>
describeHerwigGluonMassGenerator("Herwig::GluonMassGenerator", "");
void GluonMassGenerator::Init() {
static ClassDocumentation<GluonMassGenerator> documentation
("Dynamic gluon mass generation");
}
diff --git a/Hadronization/GluonMassGenerator.h b/Hadronization/GluonMassGenerator.h
--- a/Hadronization/GluonMassGenerator.h
+++ b/Hadronization/GluonMassGenerator.h
@@ -1,171 +1,151 @@
// -*- C++ -*-
//
// GluonMassGenerator.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_GluonMassGenerator_H
#define Herwig_GluonMassGenerator_H
//
// This is the declaration of the GluonMassGenerator class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/EventRecord/Particle.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Hadronization
* \brief Dynamic gluon mass generator; the default returns a constant mass.
*
* @see \ref GluonMassGeneratorInterfaces "The interfaces"
* defined for GluonMassGenerator.
*/
class GluonMassGenerator: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- GluonMassGenerator();
-
- /**
- * The destructor.
- */
- virtual ~GluonMassGenerator();
- //@}
-
-public:
-
/**
* Generate a single gluon mass with possible reference to a hard
* scale Q and up to a maximum value
*/
virtual Energy generate(Energy, Energy) const {
return generate();
}
/**
* Generate a single gluon mass with possible reference to a hard
* scale Q
*/
virtual Energy generate(Energy) const {
return generate();
}
/**
* Generate a single gluon mass without further constraints
*/
virtual Energy generate() const {
return getParticleData(ThePEG::ParticleID::g)->constituentMass();
}
/**
* Generate a list of n gluon masses, with a maximum available energy
*/
list<Energy> generateMany(size_t n, Energy QMax) const {
list<Energy> res;
- Energy m0, mu, md, ms, mg, mgmax, summg;
+ Energy m0, mu, md, ms, mg, summg;
mu=getParticleData(ThePEG::ParticleID::u)->constituentMass();
md=getParticleData(ThePEG::ParticleID::d)->constituentMass();
ms=getParticleData(ThePEG::ParticleID::s)->constituentMass();
m0=md;
if(mu<m0){m0=mu;}
if(ms<m0){m0=ms;}
if( QMax<2.0*m0*n ){
throw Exception() << "cannot reshuffle to constituent mass shells" << Exception::eventerror;
}
bool repeat=true;
while( repeat ){
repeat=false;
summg = 0.0*GeV;
res.clear();
for( size_t k = 0; k < n; ++k ){
mg = generate();
res.push_back(mg);
summg += mg;
if( summg > QMax - 2.0*m0*(n-k-1) ){
repeat=true;
break;
}
}
}
return res;
}
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.
*/
- GluonMassGenerator & operator=(const GluonMassGenerator &);
+ GluonMassGenerator & operator=(const GluonMassGenerator &) = delete;
};
}
#endif /* Herwig_GluonMassGenerator_H */
diff --git a/MatrixElement/EW/CollinearSudakov.cc b/MatrixElement/EW/CollinearSudakov.cc
deleted file mode 100644
--- a/MatrixElement/EW/CollinearSudakov.cc
+++ /dev/null
@@ -1,2075 +0,0 @@
-// -*- C++ -*-
-//
-// This is the implementation of the non-inlined, non-templated member
-// functions of the CollinearSudakov class.
-//
-
-#include "CollinearSudakov.h"
-#include "ThePEG/Interface/ClassDocumentation.h"
-#include "ThePEG/EventRecord/Particle.h"
-#include "ThePEG/Repository/UseRandom.h"
-#include "ThePEG/Repository/EventGenerator.h"
-#include "ThePEG/Utilities/DescribeClass.h"
-#include "GroupInvariants.h"
-#include "ElectroWeakReweighter.h"
-#include "ThePEG/Persistency/PersistentOStream.h"
-#include "ThePEG/Persistency/PersistentIStream.h"
-
-using namespace Herwig;
-
-namespace {
-
-void DuplicateColumn0(boost::numeric::ublas::matrix<Complex> &orig) {
- for (unsigned int i=0; i<orig.size1(); i++) {
- for (unsigned int j=1; j<orig.size2(); j++) {
- orig(i,j) = orig(i,0);
- }
- }
-}
-
-}
-
-CollinearSudakov::CollinearSudakov() : K_ORDER_(3),
- B_ORDER_(2)
-{}
-
-CollinearSudakov::~CollinearSudakov() {}
-
-IBPtr CollinearSudakov::clone() const {
- return new_ptr(*this);
-}
-
-IBPtr CollinearSudakov::fullclone() const {
- return new_ptr(*this);
-}
-
-void CollinearSudakov::persistentOutput(PersistentOStream & os) const {
- os << K_ORDER_ << B_ORDER_;
-}
-
-void CollinearSudakov::persistentInput(PersistentIStream & is, int) {
- is >> K_ORDER_ >> B_ORDER_;
-}
-
-
-// The following static variable is needed for the type
-// description system in ThePEG.
-DescribeClass<CollinearSudakov,Interfaced>
-describeHerwigCollinearSudakov("Herwig::CollinearSudakov", "HwMEEW.so");
-
-void CollinearSudakov::Init() {
-
- static ClassDocumentation<CollinearSudakov> documentation
- ("The CollinearSudakov class implements the collinear evolution");
-
-
-}
-
-
-Complex CollinearSudakov::highScaleIntegral(bool SU3, bool SU2, double Y,
- Energy2 s, Energy mu_h, Energy mu_l,
- bool fermion, bool longitudinal,
- double yukFactor) {
- SU3_ = SU3;
- SU2_ = SU2;
- Y_ = Y;
- s_ = s;
- fermion_ = fermion;
- longitudinal_ = longitudinal;
- yukFactor_ = yukFactor;
- // perform the integral
- Complex result;
- high_ = true;
- // real piece
- real_ = true;
- result.real(integrator_.value(*this,mu_h,mu_l));
- // imaginary piece
- real_ = false;
- result.imag(integrator_.value(*this,mu_h,mu_l));
- // return the answer
- return exp(result);
-}
-
-Complex CollinearSudakov::lowScaleIntegral(bool SU3, double Q, Energy2 s,
- Energy mu_h, Energy mu_l, bool fermion,
- double boostFactor) {
- SU3_ = SU3;
- Q_ = Q;
- s_ = s;
- fermion_ = fermion;
- boostFactor_ = boostFactor;
- // perform the integral
- Complex result;
- high_ = false;
- // real piece
- real_ = true;
- result.real(integrator_.value(*this,mu_h,mu_l));
- // imaginary piece
- real_ = false;
- result.imag(integrator_.value(*this,mu_h,mu_l));
- // return the answer
- return exp(result);
-}
-
-InvEnergy CollinearSudakov::highScaleIntegrand(Energy mu) const {
- using namespace GroupInvariants;
- using Constants::pi;
- Complex gamma = 0.0;
- // Include K-factor Contributions (Cusps):
- GaugeContributions cusp = cuspContributions(mu,K_ORDER_,high_);
- // Include B-factors (B1 for U1, B2 for SU2, B3 for SU3):
- GaugeContributions nonCusp = BContributions(mu,B_ORDER_,fermion_,longitudinal_);
- // common log
- Complex plog = PlusLog(s_/sqr(mu));
- // SU(3)
- if(SU3_) {
- if(fermion_)
- gamma += C_F(3)*cusp.SU3*0.5*plog + 0.5*nonCusp.SU3;
- else
- gamma += (C_A(3))*cusp.SU3*0.5*plog + 0.5*nonCusp.SU3;
- }
- // SU(2)
- if(SU2_) {
- if (fermion_ || longitudinal_ )
- gamma += (C_F(2))*cusp.SU2*0.5*plog + 0.5*nonCusp.SU2;
- else
- gamma += (C_A(2))*cusp.SU2*0.5*plog + 0.5*nonCusp.SU2;
- }
-
- if (fermion_ || longitudinal_ ) {
- gamma += sqr(Y_)*(cusp.U1*0.5*plog + 0.5*nonCusp.U1);
- }
- else {
- // U(1) Gauge boson
- if (!SU3_ && !SU2_ && abs(Y_)<0.001) {
- gamma += 0.5*nonCusp.U1;
- }
- }
- // top Yukawa piece
- double y_t = ElectroWeakReweighter::coupling()->y_t(mu);
- gamma += yukFactor_*sqr(y_t)/(16.0*sqr(pi));
- // return the answer
- return real_ ? gamma.real()/mu : gamma.imag()/mu;
-}
-
-InvEnergy CollinearSudakov::lowScaleIntegrand(Energy mu) const {
- using namespace GroupInvariants;
- using Constants::pi;
- Complex gamma = 0.0;
- // Include K-factor Contributions (Cusps):
- GaugeContributions cusp = cuspContributions(mu,K_ORDER_,false);
- // Include B-factors (B1 for U1, B2 for SU2, B3 for SU3):
- GaugeContributions nonCusp = BContributionsLow(mu,B_ORDER_,fermion_,boostFactor_);
- // common log
- Complex plog = PlusLog(s_/sqr(mu));
- Complex blog(0.);
- if(boostFactor_ >0.001) blog = PlusLog(4.0*boostFactor_);
- // SU(3)
- if (SU3_) {
- if (fermion_) {
- // not a bHQET top quark field
- if (abs(boostFactor_)<0.001)
- gamma += C_F(3)*cusp.SU3*0.5*plog + 0.5*nonCusp.SU3;
- else
- gamma += C_F(3)*cusp.SU3*0.5*blog + 0.5*nonCusp.SU3;
- }
- else {
- gamma += C_A(3)*cusp.SU3*0.5*plog + 0.5*nonCusp.SU3;
- }
- }
- // fermions
- if (fermion_) {
- // not a bHQET top quark field
- if (abs(boostFactor_)<0.001)
- gamma += sqr(Q_)*(cusp.U1*0.5*plog + 0.5*nonCusp.U1);
- else
- gamma += sqr(Q_)*(cusp.U1*0.5*blog + 0.5*nonCusp.U1);
- }
- else {
- // i.e., not a fermion, not a bHQ, not a gluon => photon
- if (abs(boostFactor_)<0.001 && !SU3_)
- gamma += 0.5*nonCusp.U1;
- // i.e., W treated as a bHQET field
- else if (abs(boostFactor_)>0.001)
- gamma += sqr(Q_)*(cusp.U1*0.5*blog + 0.5*nonCusp.U1);
- }
- // return the answer
- return real_ ? gamma.real()/mu : gamma.imag()/mu;
-}
-
-void CollinearSudakov::evaluateHighScale(Energy highScale, Energy EWScale, Energy2 S) {
- double yCoeffQt(0.), yCoefftR(0.), yCoeffPhi(0.);
- if (K_ORDER_ >= 1) {
- yCoeffQt = 0.5;
- yCoefftR = 1.0;
- yCoeffPhi = 3.0;
- }
- highColW_ = highScaleIntegral(false,true ,0.0 ,S,highScale,EWScale,false,false,0.0);
- highColB_ = highScaleIntegral(false,false,0.0 ,S,highScale,EWScale,false,false,0.0);
- highColG_ = highScaleIntegral(true ,false,0.0 ,S,highScale,EWScale,false,false,0.0);
- highColQ_ = highScaleIntegral(true ,true ,1./6. ,S,highScale,EWScale,true,false,0.0);
- highColQt_ = highScaleIntegral(true ,true ,1./6. ,S,highScale,EWScale,true,false,yCoeffQt);
- highColU_ = highScaleIntegral(true ,false,2./3. ,S,highScale,EWScale,true,false,0.0);
- highColtR_ = highScaleIntegral(true ,false,2./3. ,S,highScale,EWScale,true,false,yCoefftR);
- highColD_ = highScaleIntegral(true ,false,-1./3.,S,highScale,EWScale,true,false,0.0);
- highColL_ = highScaleIntegral(false,true ,-1./2.,S,highScale,EWScale,true,false,0.0);
- highColE_ = highScaleIntegral(false,false,-1. ,S,highScale,EWScale,true,false,0.0);
- highColPhi_ = highScaleIntegral(false,true ,1./2. ,S,highScale,EWScale,false,true,yCoeffPhi);
-}
-
-void CollinearSudakov::evaluateLowScale(Energy EWScale, Energy lowScale, Energy2 S) {
- lowColW_ = lowScaleIntegral(false,1. ,S,EWScale,lowScale,false,
- S/sqr(2.*ElectroWeakReweighter::coupling()->mW()));
- lowColA_ = lowScaleIntegral(false,0. ,S,EWScale,lowScale,false,0.0);
- lowColG_ = lowScaleIntegral(true ,0. ,S,EWScale,lowScale,false,0.0);
- lowColU_ = lowScaleIntegral(true ,2./3. ,S,EWScale,lowScale,true,0.0);
- lowColt_ = lowScaleIntegral(true ,2./3. ,S,EWScale,lowScale,true,
- S/sqr(2.*ElectroWeakReweighter::coupling()->mT()));
- lowColD_ = lowScaleIntegral(true ,-1./3.,S,EWScale,lowScale,true,0.0);
- lowColE_ = lowScaleIntegral(false,-1. ,S,EWScale,lowScale,true,0.0);
-}
-
-void CollinearSudakov::evaluateMatching(Energy EWScale,Energy2 s) {
- using Constants::pi;
- using GroupInvariants::PlusLog;
- static const Complex I(0,1.0);
- // wave function corrections
- WaveFunctionCorrections WFC = waveFunctionCorrections(EWScale);
-
- double aS = ElectroWeakReweighter::coupling()->a3(EWScale);
- double aEM = ElectroWeakReweighter::coupling()->aEM(EWScale);
- double aW = ElectroWeakReweighter::coupling()->aW(EWScale);
- double aZ = ElectroWeakReweighter::coupling()->aZ(EWScale);
- double cW2 = ElectroWeakReweighter::coupling()->Cos2thW(EWScale);
- double sW2 = ElectroWeakReweighter::coupling()->Sin2thW(EWScale);
- Energy mW = ElectroWeakReweighter::coupling()->mW();
- Energy mZ = ElectroWeakReweighter::coupling()->mZ();
- Energy mH = ElectroWeakReweighter::coupling()->mH();
- Energy mT = ElectroWeakReweighter::coupling()->mT();
- double gPHI = ElectroWeakReweighter::coupling()->g_phiPlus(EWScale);
- double y_t = ElectroWeakReweighter::coupling()->y_t(EWScale);
-
- double lz = log(mZ/EWScale);
- double lw = log(mW/EWScale);
-
- complex<double> F_W = 4.0*lw*0.5*PlusLog(s/EWScale/EWScale)-2.0*lw*lw-2.0*lw-5.0*pi*pi/12.0+1.0;
- complex<double> F_Z = 4.0*lz*0.5*PlusLog(s/EWScale/EWScale)-2.0*lz*lz-2.0*lz-5.0*pi*pi/12.0+1.0;
-
- // Taken from Manohar... along with his formulae for F_tL, F_tR, and F_bL (for 3rd/1st Gen. Wavefunction Differences)
- complex<double> W1 = WFC.fFW0-0.5*WFC.aW0-0.5*WFC.cW0;
- complex<double> W2 = WFC.fF0W-0.5*WFC.a0W;
- complex<double> U1 = ElectroWeakReweighter::coupling()->g_Lu(EWScale)*ElectroWeakReweighter::coupling()->g_Lu(EWScale)*(WFC.fFZZ-0.5*WFC.aZZ) -
- 0.5*WFC.cZZ*(ElectroWeakReweighter::coupling()->g_Lu(EWScale)*ElectroWeakReweighter::coupling()->g_Lu(EWScale) +
- ElectroWeakReweighter::coupling()->g_Ru(EWScale)*ElectroWeakReweighter::coupling()->g_Ru(EWScale)) +
- ElectroWeakReweighter::coupling()->g_Lu(EWScale)*ElectroWeakReweighter::coupling()->g_Ru(EWScale)*WFC.bZZ;
- complex<double> U2 = ElectroWeakReweighter::coupling()->g_Ru(EWScale)*ElectroWeakReweighter::coupling()->g_Ru(EWScale)*(WFC.fFZZ-0.5*WFC.aZZ) -
- 0.5*WFC.cZZ*(ElectroWeakReweighter::coupling()->g_Lu(EWScale)*ElectroWeakReweighter::coupling()->g_Lu(EWScale) +
- ElectroWeakReweighter::coupling()->g_Ru(EWScale)*ElectroWeakReweighter::coupling()->g_Ru(EWScale)) +
- ElectroWeakReweighter::coupling()->g_Lu(EWScale)*ElectroWeakReweighter::coupling()->g_Ru(EWScale)*WFC.bZZ;
- complex<double> HtL = -0.5*y_t*y_t/(16.0*pi*pi)*(0.25-0.5*log(mH/EWScale)-0.5*lz+
- 0.5*WFC.atHH+0.5*WFC.atZZ+WFC.ctHH+WFC.ctZZ+
- WFC.ctW0-WFC.btHH+WFC.btZZ);
- complex<double> HtR = HtL-0.5*y_t*y_t/(16.0*pi*pi)*(0.25-lw+WFC.atW0);
- complex<double> HbL = -0.5*y_t*y_t/(16.0*pi*pi)*(0.25-lw+WFC.at0W);
-
- complex<double> F_tL = (4.0/3.0*aS+4.0/9.0*aEM)/(4.0*pi)*(2.0*log(mT/EWScale)*log(mT/EWScale)-log(mT/EWScale)+
- pi*pi/12.0+2.0) + HtL +
- aW/(4.0*pi)*0.5*W1 + aZ/(4.0*pi)*U1;
-
- complex<double> F_tR = (4.0/3.0*aS+4.0/9.0*aEM)/(4.0*pi)*(2.0*log(mT/EWScale)*log(mT/EWScale)-log(mT/EWScale)+
- pi*pi/12.0+2.0) + HtR -
- aW/(4.0*pi)*0.25*WFC.cW0 + aZ/(4.0*pi)*U2;
-
- complex<double> F_bL = HbL + aW/(4.0*pi)*0.5*W2;
-
- Complex Dw = CollinearDw(s,EWScale);
- Complex Dz = CollinearDz(s,EWScale);
-
- complex<double> D_C_UL = ElectroWeakReweighter::coupling()->g_Lu(EWScale)*ElectroWeakReweighter::coupling()->g_Lu(EWScale)*Dz + 0.5*Dw;
- complex<double> D_C_DL = ElectroWeakReweighter::coupling()->g_Ld(EWScale)*ElectroWeakReweighter::coupling()->g_Ld(EWScale)*Dz + 0.5*Dw;
-
- complex<double> D_C_UR = ElectroWeakReweighter::coupling()->g_Ru(EWScale)*ElectroWeakReweighter::coupling()->g_Ru(EWScale)*Dz;
- complex<double> D_C_DR = ElectroWeakReweighter::coupling()->g_Rd(EWScale)*ElectroWeakReweighter::coupling()->g_Rd(EWScale)*Dz;
-
- complex<double> D_C_nuL = ElectroWeakReweighter::coupling()->g_Lnu(EWScale)*ElectroWeakReweighter::coupling()->g_Lnu(EWScale)*Dz + 0.5*Dw;
- complex<double> D_C_EL = ElectroWeakReweighter::coupling()->g_Le(EWScale)*ElectroWeakReweighter::coupling()->g_Le(EWScale)*Dz + 0.5*Dw;
- complex<double> D_C_ER = ElectroWeakReweighter::coupling()->g_Re(EWScale)*ElectroWeakReweighter::coupling()->g_Re(EWScale)*Dz;
-
- complex<double> D_C_WW = aW/(4.0*pi)*cW2*(F_Z+WFC.fsWZWZ) +
- aW/(4.0*pi)*cW2*(F_W+WFC.fs1ZW) + aW/(4.0*pi)*sW2*(F_W+WFC.fs10) +
- aW/(4.0*pi)*sW2*(2.0*lw*lw-
- 2.0*lw+pi*pi/12.0+2.0) + 0.5*WFC.RW;
- complex<double> D_C_WZ = aW/(4.0*pi)*2.0*(F_W+WFC.fsZW1) + 0.5*WFC.RZ + sqrt(sW2/cW2)*WFC.RAtoZ;
- complex<double> D_C_WA = aW/(4.0*pi)*2.0*(F_W+WFC.fs01) + 0.5*WFC.RA + sqrt(cW2/sW2)*WFC.RZtoA;
- complex<double> D_C_BZ = 0.5*WFC.RZ - sqrt(cW2/sW2)*WFC.RAtoZ;
- complex<double> D_C_BA = 0.5*WFC.RA - sqrt(sW2/cW2)*WFC.RZtoA;
-
- // The WFC.RW and WFC.RZ are used on purpose (instead of WFC.RPhi and WFC.RPhi3, respectively):
- complex<double> D_C_PhiW = aW/(4.0*pi)*0.25*(F_W+WFC.fs1HW) +
- aW/(4.0*pi)*0.25*(F_W+WFC.fs1ZW) + aZ/(4.0*pi)*gPHI*gPHI*(F_Z+WFC.fsWZWZ) +
- aW/(4.0*pi)*sW2*(2.0*lw*lw-2.0*lw+pi*pi/12.0+2.0) +
- 0.5*WFC.RW + WFC.EW;
- complex<double> D_C_PhiZ = aW/(4.0*pi)*0.5*(F_W+WFC.fsZW1) + aZ/(4.0*pi)*0.25*(F_Z+WFC.fs1HZ) + 0.5*WFC.RZ + WFC.EZ;
- complex<double> D_C_PhiH = aW/(4.0*pi)*0.5*(F_W+WFC.fsHW1) + aZ/(4.0*pi)*0.25*(F_Z+WFC.fsHZ1) + 0.5*WFC.RH;
-
- complex<double> D_C_GG = aS/(4.0*pi)*2.0/3.0*log(mT/EWScale);
-
- ULcollinearCorr_ = exp(D_C_UL);
- DLcollinearCorr_ = exp(D_C_DL);
- URcollinearCorr_ = exp(D_C_UR);
- DRcollinearCorr_ = exp(D_C_DR);
-
- tLcollinearCorr_ = exp(D_C_UL+F_tL);
- tRcollinearCorr_ = exp(D_C_UR+F_tR);
- bLcollinearCorr_ = exp(D_C_DL+F_bL);
-
- nuLcollinearCorr_ = exp(D_C_nuL);
- ELcollinearCorr_ = exp(D_C_EL);
- ERcollinearCorr_ = exp(D_C_ER);
-
- WtoWcollinearCorr_ = exp(D_C_WW);
- WtoZcollinearCorr_ = exp(D_C_WZ);
- WtoAcollinearCorr_ = exp(D_C_WA);
- BtoZcollinearCorr_ = exp(D_C_BZ);
- BtoAcollinearCorr_ = exp(D_C_BA);
-
- PhitoWcollinearCorr_ = exp(D_C_PhiW);
- PhitoZcollinearCorr_ = exp(D_C_PhiZ);
- PhitoHcollinearCorr_ = exp(D_C_PhiH);
-
- GcollinearCorr_ = exp(D_C_GG);
-}
-
-WaveFunctionCorrections CollinearSudakov::waveFunctionCorrections(Energy EWScale) {
- static const Complex I(0.,1.);
- using Constants::pi;
- double lZ = 2.0*log(ElectroWeakReweighter::coupling()->mZ()/EWScale);
- WaveFunctionCorrections WFC;
- // From Manohar, 2/12/12: (these assume mH=125, mZ=91.1876, mW=80.399)
- WFC.RW = (0.8410283377963967 - 9.424777961271568*I) + 1.2785863646210789*lZ;
- WFC.RA = (1.4835982362022198 + 1.855775680704845*pow(10.,-9)*I) - 0.27209907467584415*lZ;
- WFC.RZ = (1.5114724841549798 - 9.926944419863688*I) + 1.0834802397165764*lZ;
- WFC.RAtoZ = (0.3667485032811715 - 2.2770907130064835*I) - 1.2994544609942593*lZ;
- WFC.RZtoA = -0.2095310079712942 + 0.8320191107808546*lZ;
- WFC.RH = (12.229832449946716 - 1.7643103462419842*10.0*pow(10.,-12)*I) + 5.309998583664737*lZ;
- WFC.RPhi = (5.569012418081201 + 1.5439133581417356*0.10*pow(10.,-9)*I) + 5.309998583664737*lZ;
- WFC.RPhi3 = (8.945333042265943 + 5.499309445612249*pow(10.,-12)*I) + 5.309998583664737*lZ;
- WFC.EW = (3.967645734304811 + 4.712388980384717*I) + 2.238332625165702*lZ;
- WFC.EZ = (5.916079892937651 + 4.96347220970469*I) + 2.1132591719740788*lZ;
-
- WFC.RW *= ElectroWeakReweighter::coupling()->a2(EWScale)/(4.0*pi);
- WFC.RA *= ElectroWeakReweighter::coupling()->a2(EWScale)/(4.0*pi);
- WFC.RZ *= ElectroWeakReweighter::coupling()->a2(EWScale)/(4.0*pi);
- WFC.RAtoZ *= ElectroWeakReweighter::coupling()->a2(EWScale)/(4.0*pi);
- WFC.RZtoA *= ElectroWeakReweighter::coupling()->a2(EWScale)/(4.0*pi);
- WFC.RPhi *= ElectroWeakReweighter::coupling()->a2(EWScale)/(4.0*pi);
- WFC.EW *= ElectroWeakReweighter::coupling()->a2(EWScale)/(4.0*pi);
- WFC.EZ *= ElectroWeakReweighter::coupling()->a2(EWScale)/(4.0*pi);
- WFC.RPhi3 *= ElectroWeakReweighter::coupling()->a2(EWScale)/(4.0*pi);
- WFC.RH *= ElectroWeakReweighter::coupling()->a2(EWScale)/(4.0*pi);
-
-
- WFC.RW = WFC.RW.real();
- WFC.RA = WFC.RA.real();
- WFC.RZ = WFC.RZ.real();
- WFC.RAtoZ = WFC.RAtoZ.real();
- WFC.RZtoA = WFC.RZtoA.real();
- WFC.RPhi = WFC.RPhi.real();
- WFC.RPhi3 = WFC.RPhi3.real();
- WFC.RH = WFC.RH.real();
-
- // Also from Manohar, 2/10/12
- WFC.fFW0 = -3.7946842553189453 - 4.709019671388589*I;
- WFC.fF0W = 3.8181790485161176;
- WFC.fFZZ = 1.364503250377989 + 0.*I;
- WFC.aHH = -0.474396977740686 + 0.*I;
- WFC.aZZ = -0.6806563210877914 + 0.*I;
- WFC.aW0 = 0.49036102506811907 + 1.9323351450971642*I;
- WFC.a0W = -1.2184776671065072;
- WFC.bHH = 1.234775745474991 + 0.*I;
- WFC.bZZ = 1.7303526426747613 + 0.*I;
- WFC.cHH = 0.33140608274387473 + 0.*I;
- WFC.cZZ = 0.4961363208382017 + 0.*I;
- WFC.cW0 = -1.005299829777395 + 1.063048500002757*I;
- WFC.atHH = -0.237198488870343 + 0.*I;
- WFC.atZZ = -0.3403281605438957 + 0.*I;
- WFC.atW0 = 0.24518051253405954 + 0.9661675725485821*I;
- WFC.at0W = -0.6092388335532536;
- WFC.ctHH = 0.16570304137193737 + 0.*I;
- WFC.ctZZ = 0.24806816041910085 + 0.*I;
- WFC.ctW0 = -0.5026499148886975 + 0.5315242500013785*I;
- WFC.btHH = -0.30869393636874776 + 0.*I;
- WFC.btZZ = -0.4325881606686903 + 0.*I;
-
- WFC.fs10 = -2.289868133696459;
- WFC.fs1ZW = 1.8627978596240622;
- WFC.fsWZWZ = 1.1866922529667008;
- WFC.fsZW1 = 1.0840307611156266;
- WFC.fs01 = 2.2898681336964595;
- WFC.fsHW1 = -0.32306745562682404;
- WFC.fsHZ1 = 0.4042992116255279;
- WFC.fs1HW = 3.330954543719127;
- WFC.fs1HZ = 2.69768201932412;
- return WFC;
-}
-
-Complex CollinearSudakov::CollinearDw(Energy2 s, Energy EWScale) {
- using Constants::pi;
- using GroupInvariants::PlusLog;
- double lw = log(ElectroWeakReweighter::coupling()->mW()/EWScale);
- //s = s/2.; // This should not be here... I think this is a discrepency with Sascha
- return ElectroWeakReweighter::coupling()->aW(EWScale)/(4.0*pi)*
- (4.0*lw*0.5*PlusLog(s/EWScale/EWScale) - 2.0*lw*lw -
- 3.0*lw - 5.0/12.0*pi*pi + 9.0/4.0);
-}
-
-Complex CollinearSudakov::CollinearDz(Energy2 s, Energy EWScale) {
- using Constants::pi;
- using GroupInvariants::PlusLog;
- double lz = log(ElectroWeakReweighter::coupling()->mZ()/EWScale);
- return ElectroWeakReweighter::coupling()->aZ(EWScale)/(4.0*pi)*
- (4.0*lz*0.5*PlusLog(s/EWScale/EWScale) - 2.0*lz*lz -
- 3.0*lz - 5.0/12.0*pi*pi + 9.0/4.0);
-}
-
-namespace {
-
-void writeLine(ofstream & file, vector<Energy> x, vector<double> y,
- string name,string title,
- string colour, string style) {
- file << "# BEGIN HISTO1D "+name +"\n";
- file << "SmoothLine=1\n";
- file << "ErrorBars=0\n";
- file << "Path="+name+"\n";
- file << "Title="+title+"\n";
- file << "LineColor="+colour+"\n";
- file << "LineStyle="+style +"\n";
- file << "# xlow xhigh val errminus errplus\n";
- for(unsigned int ix=0;ix<x.size();++ix)
- file << (x[ix]-MeV)/GeV << "\t" << (x[ix]+MeV)/GeV << "\t"
- << y[ix] << "\t" << 0. << "\t" << 0. << "\n";
- file << "# END HISTO1D\n";
-}
-
-}
-
-void CollinearSudakov::makePlots() {
- vector<Energy> np;
- vector<double> uL,uR,tL,tR,dL,dR,bL,bR,nuL,eL,eR,Wgamma,Bgamma,g,WT,WL,WZT,BZT,ZL,H;
- Energy mZ = ElectroWeakReweighter::coupling()->mZ();
- for(Energy x=200.*GeV;x<5000.*GeV;x*=1.02) {
- Energy2 s(sqr(x));
- np.push_back(x);
- evaluateHighScale(x,mZ,s);
- evaluateMatching(mZ,s);
- uL .push_back(real(highColQ_ * ULcollinearCorr_ ));
- uR .push_back(real(highColU_ * URcollinearCorr_ ));
- tL .push_back(real(highColQt_ * tLcollinearCorr_ ));
- tR .push_back(real(highColtR_ * tRcollinearCorr_ ));
- dL .push_back(real(highColQ_ * DLcollinearCorr_ ));
- dR .push_back(real(highColD_ * DRcollinearCorr_ ));
- bL .push_back(real(highColQt_ * bLcollinearCorr_ ));
- bR .push_back(real(highColD_ * DRcollinearCorr_ ));
- nuL .push_back(real(highColL_ * nuLcollinearCorr_ ));
- eL .push_back(real(highColL_ * ELcollinearCorr_ ));
- eR .push_back(real(highColE_ * ERcollinearCorr_ ));
- Wgamma.push_back(real(highColW_ * WtoAcollinearCorr_ ));
- Bgamma.push_back(real(highColB_ * BtoAcollinearCorr_ ));
- g .push_back(real(highColG_ * GcollinearCorr_ ));
- WT .push_back(real(highColW_ * WtoWcollinearCorr_ ));
- WL .push_back(real(highColPhi_ * PhitoWcollinearCorr_));
- WZT .push_back(real(highColW_ * WtoZcollinearCorr_ ));
- BZT .push_back(real(highColB_ * BtoZcollinearCorr_ ));
- ZL .push_back(real(highColPhi_ * PhitoZcollinearCorr_));
- H .push_back(real(highColPhi_ * PhitoHcollinearCorr_));
- }
- ofstream fig1a("fig1a.dat");
- fig1a << "#BEGIN PLOT\n";
- fig1a << "LegendOnly=/uL /uR /tL /tR\n";
- fig1a << "DrawOnly=/uL /uR /tL /tR\n";
- fig1a << "Title=Figure 1a\n";
- fig1a << "RatioPlot=0\n";
- fig1a << "LogX=1\n";
- fig1a << "XLabel=$\\bar{n}\\cdot p$ [GeV]\n";
- fig1a << "YLabel=u, t\n";
- fig1a << "Legend=1\n";
- fig1a << "XMin=250.\n";
- fig1a << "YMin=0.7\n";
- fig1a << "YMax=1.05\n";
- fig1a << "# END PLOT\n";
- writeLine(fig1a,np,uL,"/uL","$u_L$","green","dotted" );
- writeLine(fig1a,np,uR,"/uR","$u_R$","cyan" ,"solid" );
- writeLine(fig1a,np,tL,"/tL","$t_L$","red" ,"dashed" );
- writeLine(fig1a,np,tR,"/tR","$t_R$","blue" ,"dotdashed");
- fig1a.close();
- ofstream fig1b("fig1b.dat");
- fig1b << "#BEGIN PLOT\n";
- fig1b << "LegendOnly=/dL /dR /bL /bR\n";
- fig1b << "DrawOnly=/dL /dR /bL /bR\n";
- fig1b << "Title=Figure 1b\n";
- fig1b << "RatioPlot=0\n";
- fig1b << "LogX=1\n";
- fig1b << "XLabel=$\\bar{n}\\cdot p$ [GeV]\n";
- fig1b << "YLabel=d, b\n";
- fig1b << "Legend=1\n";
- fig1b << "XMin=250.\n";
- fig1b << "YMin=0.7\n";
- fig1b << "YMax=1.05\n";
- fig1b << "# END PLOT\n";
- writeLine(fig1b,np,dL,"/dL","$d_L$","green","dotted" );
- writeLine(fig1b,np,dR,"/dR","$d_R$","cyan" ,"solid" );
- writeLine(fig1b,np,bL,"/bL","$b_L$","red" ,"dashed" );
- writeLine(fig1b,np,bR,"/bR","$b_R$","blue" ,"dotdashed");
- fig1b.close();
- ofstream fig2("fig2.dat");
- fig2 << "#BEGIN PLOT\n";
- fig2 << "LegendOnly=/uL /uR /dL /dR\n";
- fig2 << "DrawOnly=/uL /uR /dL /dR\n";
- fig2 << "Title=Figure 2\n";
- fig2 << "RatioPlot=0\n";
- fig2 << "LogX=1\n";
- fig2 << "XLabel=$\\bar{n}\\cdot p$ [GeV]\n";
- fig2 << "YLabel=u, d\n";
- fig2 << "Legend=1\n";
- fig2 << "XMin=250.\n";
- fig2 << "YMin=0.7\n";
- fig2 << "YMax=1.05\n";
- fig2 << "# END PLOT\n";
- writeLine(fig2,np,uL,"/uL","$u_L$","green","dotted" );
- writeLine(fig2,np,uR,"/uR","$u_R$","cyan" ,"solid" );
- writeLine(fig2,np,dL,"/dL","$d_L$","red" ,"dashed" );
- writeLine(fig2,np,dR,"/dR","$d_R$","blue" ,"dotdashed");
- fig2.close();
- ofstream fig3("fig3.dat");
- fig3 << "#BEGIN PLOT\n";
- fig3 << "LegendOnly=/nuL /eL /eR\n";
- fig3 << "DrawOnly=/nuL /eL /eR\n";
- fig3 << "Title=Figure 3\n";
- fig3 << "RatioPlot=0\n";
- fig3 << "LogX=1\n";
- fig3 << "XLabel=$\\bar{n}\\cdot p$ [GeV]\n";
- fig3 << "YLabel=$\\nu$, $e$\n";
- fig3 << "Legend=1\n";
- fig3 << "XMin=250.\n";
- fig3 << "YMin=0.9\n";
- fig3 << "YMax=1.05\n";
- fig3 << "# END PLOT\n";
- writeLine(fig3,np,nuL,"/nuL","$\\nu_L$","blue","dashed");
- writeLine(fig3,np, eL,"/eL" ,"$e_L$" ,"red" ,"dotted");
- writeLine(fig3,np, eR,"/eR" ,"$e_R$" ,"red" ,"solid" );
- fig3.close();
- ofstream fig5("fig5.dat");
- fig5 << "#BEGIN PLOT\n";
- fig5 << "LegendOnly=/g /Wgamma /Bgamma\n";
- fig5 << "DrawOnly=/g /Wgamma /Bgamma\n";
- fig5 << "Title=Figure 5\n";
- fig5 << "RatioPlot=0\n";
- fig5 << "LogX=1\n";
- fig5 << "XLabel=$\\bar{n}\\cdot p$ [GeV]\n";
- fig5 << "YLabel=$\\gamma$, g\n";
- fig5 << "Legend=1\n";
- fig5 << "XMin=250.\n";
- fig5 << "YMin=0.7\n";
- fig5 << "YMax=1.05\n";
- fig5 << "# END PLOT\n";
- writeLine(fig5,np,g ,"/g" ,"$g$" ,"blue","dashed");
- writeLine(fig5,np,Wgamma,"/Wgamma","$W\\to\\gamma$","red" ,"solid" );
- writeLine(fig5,np,Bgamma,"/Bgamma","$B\\to\\gamma$","red" ,"dotted");
- fig5.close();
- ofstream fig6a("fig6a.dat");
- fig6a << "#BEGIN PLOT\n";
- fig6a << "LegendOnly=/WT /WL\n";
- fig6a << "DrawOnly=/WT /WL\n";
- fig6a << "Title=Figure 6a\n";
- fig6a << "RatioPlot=0\n";
- fig6a << "LogX=1\n";
- fig6a << "XLabel=$\\bar{n}\\cdot p$ [GeV]\n";
- fig6a << "YLabel=$Z_L$, $Z_T$, $H$\n";
- fig6a << "Legend=1\n";
- fig6a << "XMin=250.\n";
- fig6a << "YMin=0.7\n";
- fig6a << "YMax=1.05\n";
- fig6a << "# END PLOT\n";
- writeLine(fig6a,np,WT,"/WT","$W_T$","red" ,"solid");
- writeLine(fig6a,np,WL,"/WL","$W_L$","blue" ,"dashed" );
- fig6a.close();
- ofstream fig6b("fig6b.dat");
- fig6b << "#BEGIN PLOT\n";
- fig6b << "LegendOnly=/WZT /BZT /ZL /H\n";
- fig6b << "DrawOnly=/WZT /BZT /ZL /H\n";
- fig6b << "Title=Figure 6b\n";
- fig6b << "RatioPlot=0\n";
- fig6b << "LogX=1\n";
- fig6b << "XLabel=$\\bar{n}\\cdot p$ [GeV]\n";
- fig6b << "YLabel=d, b\n";
- fig6b << "Legend=1\n";
- fig6b << "XMin=250.\n";
- fig6b << "YMin=0.7\n";
- fig6b << "YMax=1.05\n";
- fig6b << "# END PLOT\n";
- writeLine(fig6b,np,WZT,"/WZT","$W\\to Z_T$","red" ,"solid" );
- writeLine(fig6b,np,BZT,"/BZT","$B\\to Z_T$","red" ,"dotted" );
- writeLine(fig6b,np,ZL ,"/ZL ","$Z_L$" ,"blue" ,"dashed" );
- writeLine(fig6b,np,H ,"/H ","$H$" ,"green","dotdashed");
- fig6b.close();
-
-
- np.clear();
- vector<double> e30,e50,q30,q50,g30,g50;
- for(Energy x=200.*GeV;x<5000.*GeV;x*=1.02) {
- Energy2 s(sqr(x));
- np.push_back(x);
- evaluateLowScale(mZ,30.*GeV,s);
- e30.push_back(real(lowColE_));
- q30.push_back(real(lowColU_));
- g30.push_back(real(lowColG_));
- evaluateLowScale(mZ,50.*GeV,s);
- e50.push_back(real(lowColE_));
- q50.push_back(real(lowColU_));
- g50.push_back(real(lowColG_));
- }
- ofstream fig4a("fig4a.dat");
- fig4a << "#BEGIN PLOT\n";
- fig4a << "LegendOnly=/e30 /e50\n";
- fig4a << "DrawOnly=/e30 /e50\n";
- fig4a << "Title=Figure 4a\n";
- fig4a << "RatioPlot=0\n";
- fig4a << "LogX=1\n";
- fig4a << "XLabel=$\\bar{n}\\cdot p$ [GeV]\n";
- fig4a << "YLabel=e\n";
- fig4a << "Legend=1\n";
- fig4a << "XMin=250.\n";
- fig4a << "YMin=0.7\n";
- fig4a << "YMax=1.05\n";
- fig4a << "# END PLOT\n";
- writeLine(fig4a,np,e30,"/e30","e $(\\mu_f=30\\,\\mathrm{GeV})$","red" ,"solid" );
- writeLine(fig4a,np,e50,"/e50","e $(\\mu_f=50\\,\\mathrm{GeV})$","blue","dashed");
- fig4a.close();
- ofstream fig4b("fig4b.dat");
- fig4b << "#BEGIN PLOT\n";
- fig4b << "LegendOnly=/q30 /q50 /g30 /g50\n";
- fig4b << "DrawOnly=/q30 /q50 /g30 /g50\n";
- fig4b << "Title=Figure 4a\n";
- fig4b << "RatioPlot=0\n";
- fig4b << "LogX=1\n";
- fig4b << "XLabel=$\\bar{n}\\cdot p$ [GeV]\n";
- fig4b << "YLabel=e\n";
- fig4b << "Legend=1\n";
- fig4b << "XMin=250.\n";
- fig4b << "YMin=0.5\n";
- fig4b << "YMax=1.05\n";
- fig4b << "# END PLOT\n";
- writeLine(fig4b,np,q30,"/q30","q $(\\mu_f=30\\,\\mathrm{GeV})$","red" ,"solid" );
- writeLine(fig4b,np,q50,"/q50","q $(\\mu_f=50\\,\\mathrm{GeV})$","blue","dashed");
- writeLine(fig4b,np,g30,"/g30","g $(\\mu_f=30\\,\\mathrm{GeV})$","green" ,"dotted" );
- writeLine(fig4b,np,g50,"/g50","g $(\\mu_f=50\\,\\mathrm{GeV})$","blue","dotdashed");
- fig4b.close();
-}
-
-boost::numeric::ublas::matrix<Complex>
-CollinearSudakov::electroWeakMatching(Energy EWScale, Energy2 s,
- Herwig::EWProcess::Process process,
- bool oneLoop) {
- using namespace EWProcess;
- // calculate the matching coefficients
- evaluateMatching(EWScale,s);
- // fill the matrix
- boost::numeric::ublas::matrix<Complex> result(1,1);
- switch (process) {
- case QQQQ:
- case QQQQiden:
- {
- unsigned int numGauge = 4, numBrokenGauge = 12;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- result(0,0) = result(6,0) = ULcollinearCorr_*ULcollinearCorr_*ULcollinearCorr_*ULcollinearCorr_;
- result(3,0) = result(9,0) = DLcollinearCorr_*DLcollinearCorr_*DLcollinearCorr_*DLcollinearCorr_;
- for (int i=0; i<12; i++) {
- if (i!=0 && i!=3 && i!=6 && i!=9) {
- result(i,0) = ULcollinearCorr_*ULcollinearCorr_*DLcollinearCorr_*DLcollinearCorr_;
- }
- }
- DuplicateColumn0(result);
- }
- break;
- case QtQtQQ:
- {
- unsigned int numGauge = 4, numBrokenGauge = 12;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- result(0,0) = result(6,0) = ULcollinearCorr_*ULcollinearCorr_*tLcollinearCorr_*tLcollinearCorr_;
- result(3,0) = result(9,0) = DLcollinearCorr_*DLcollinearCorr_*bLcollinearCorr_*bLcollinearCorr_;
- for (int i=0; i<12; i++) {
- if (i==4 || i==5 || i==10 || i==11) {
- result(i,0) = ULcollinearCorr_*tLcollinearCorr_*DLcollinearCorr_*bLcollinearCorr_;
- }
- else if (i==1 || i==7) {
- result(i,0) = DLcollinearCorr_*DLcollinearCorr_*tLcollinearCorr_*tLcollinearCorr_;
- }
- else if (i==2 || i==8) {
- result(i,0) = ULcollinearCorr_*ULcollinearCorr_*bLcollinearCorr_*bLcollinearCorr_;
- }
- }
- DuplicateColumn0(result);
- }
- break;
- case QQUU:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(2,0) = ULcollinearCorr_*ULcollinearCorr_*URcollinearCorr_*URcollinearCorr_;
- result(1,0) = result(3,0) = DLcollinearCorr_*DLcollinearCorr_*URcollinearCorr_*URcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case QtQtUU:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(2,0) = tLcollinearCorr_*tLcollinearCorr_*URcollinearCorr_*URcollinearCorr_;
- result(1,0) = result(3,0) = bLcollinearCorr_*bLcollinearCorr_*URcollinearCorr_*URcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case QQtRtR:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(2,0) = ULcollinearCorr_*ULcollinearCorr_*tRcollinearCorr_*tRcollinearCorr_;
- result(1,0) = result(3,0) = DLcollinearCorr_*DLcollinearCorr_*tRcollinearCorr_*tRcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case QQDD:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(2,0) = ULcollinearCorr_*ULcollinearCorr_*DRcollinearCorr_*DRcollinearCorr_;
- result(1,0) = result(3,0) = DLcollinearCorr_*DLcollinearCorr_*DRcollinearCorr_*DRcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case QtQtDD:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(2,0) = tLcollinearCorr_*tLcollinearCorr_*DRcollinearCorr_*DRcollinearCorr_;
- result(1,0) = result(3,0) = bLcollinearCorr_*bLcollinearCorr_*DRcollinearCorr_*DRcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case QQLL:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 6;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = nuLcollinearCorr_*nuLcollinearCorr_*ULcollinearCorr_*ULcollinearCorr_;
- result(1,0) = nuLcollinearCorr_*nuLcollinearCorr_*DLcollinearCorr_*DLcollinearCorr_;
- result(2,0) = ELcollinearCorr_*ELcollinearCorr_*ULcollinearCorr_*ULcollinearCorr_;
- result(3,0) = ELcollinearCorr_*ELcollinearCorr_*DLcollinearCorr_*DLcollinearCorr_;
- result(4,0) = result(5,0) = nuLcollinearCorr_*ELcollinearCorr_*ULcollinearCorr_*DLcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case QQEE:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = ULcollinearCorr_*ULcollinearCorr_*ERcollinearCorr_*ERcollinearCorr_;
- result(1,0) = DLcollinearCorr_*DLcollinearCorr_*ERcollinearCorr_*ERcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case UUUU:
- case UUUUiden:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(1,0) = URcollinearCorr_*URcollinearCorr_*URcollinearCorr_*URcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case tRtRUU:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(1,0) = tRcollinearCorr_*tRcollinearCorr_*URcollinearCorr_*URcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case UUDD:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(1,0) = URcollinearCorr_*URcollinearCorr_*DRcollinearCorr_*DRcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case tRtRDD:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(1,0) = tRcollinearCorr_*tRcollinearCorr_*DRcollinearCorr_*DRcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case UULL:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = nuLcollinearCorr_*nuLcollinearCorr_*URcollinearCorr_*URcollinearCorr_;
- result(1,0) = ELcollinearCorr_*ELcollinearCorr_*URcollinearCorr_*URcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case UUEE:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = URcollinearCorr_*URcollinearCorr_*ERcollinearCorr_*ERcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case DDDD:
- case DDDDiden:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(1,0) = DRcollinearCorr_*DRcollinearCorr_*DRcollinearCorr_*DRcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case DDLL:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = nuLcollinearCorr_*nuLcollinearCorr_*DRcollinearCorr_*DRcollinearCorr_;
- result(1,0) = ELcollinearCorr_*ELcollinearCorr_*DRcollinearCorr_*DRcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case DDEE:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = DRcollinearCorr_*DRcollinearCorr_*ERcollinearCorr_*ERcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case LLLL:
- case LLLLiden:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 6;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = nuLcollinearCorr_*nuLcollinearCorr_*nuLcollinearCorr_*nuLcollinearCorr_;
- result(1,0) = nuLcollinearCorr_*nuLcollinearCorr_*ELcollinearCorr_*ELcollinearCorr_;
- result(2,0) = ELcollinearCorr_*ELcollinearCorr_*nuLcollinearCorr_*nuLcollinearCorr_;
- result(3,0) = ELcollinearCorr_*ELcollinearCorr_*ELcollinearCorr_*ELcollinearCorr_;
- result(4,0) = result(5,0) = nuLcollinearCorr_*ELcollinearCorr_*nuLcollinearCorr_*ELcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case LLEE:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = nuLcollinearCorr_*nuLcollinearCorr_*ERcollinearCorr_*ERcollinearCorr_;
- result(1,0) = ELcollinearCorr_*ELcollinearCorr_*ERcollinearCorr_*ERcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case EEEE:
- case EEEEiden:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = ERcollinearCorr_*ERcollinearCorr_*ERcollinearCorr_*ERcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case QQWW:
- case LLWW:
- {
- unsigned int numGauge = 5;
- unsigned int numBrokenGauge = 20;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- for (unsigned int row = 0; row < result.size1(); row++) {
- for (unsigned int col = 0; col < result.size2(); col++) {
-
- // Boson Collinear Corr_ections:
- if (col==0 || col==1) {
- if (row==0 || row==1 || row==6 || row==7) result(row,col) = (WtoWcollinearCorr_*WtoWcollinearCorr_);
- if (row==2 || row==8) result(row,col) = (WtoZcollinearCorr_*WtoZcollinearCorr_);
- if (row==3 || row==4 || row==9 || row==10) result(row,col) = (WtoZcollinearCorr_*WtoAcollinearCorr_);
- if (row==5 || row==11) result(row,col) = (WtoAcollinearCorr_*WtoAcollinearCorr_);
- if (row==12 || row==14) result(row,col) = (WtoWcollinearCorr_*WtoZcollinearCorr_);
- if (row==13 || row==15) result(row,col) = (WtoWcollinearCorr_*WtoAcollinearCorr_);
- if (row==16 || row==18) result(row,col) = (WtoWcollinearCorr_*WtoZcollinearCorr_);
- if (row==17 || row==19) result(row,col) = (WtoWcollinearCorr_*WtoAcollinearCorr_);
- }
- if (col==2) {
- if (row==2 || row==8) result(row,col) = (WtoZcollinearCorr_*BtoZcollinearCorr_);
- if (row==3 || row==9) result(row,col) = (WtoZcollinearCorr_*BtoAcollinearCorr_);
- if (row==4 || row==10) result(row,col) = (WtoAcollinearCorr_*BtoZcollinearCorr_);
- if (row==5 || row==11) result(row,col) = (WtoAcollinearCorr_*BtoAcollinearCorr_);
- if (row==14) result(row,col) = (WtoWcollinearCorr_*BtoZcollinearCorr_);
- if (row==15) result(row,col) = (WtoWcollinearCorr_*BtoAcollinearCorr_);
- if (row==16) result(row,col) = (WtoWcollinearCorr_*BtoZcollinearCorr_);
- if (row==17) result(row,col) = (WtoWcollinearCorr_*BtoAcollinearCorr_);
- }
- if (col==3) {
- if (row==2 || row==8) result(row,col) = (WtoZcollinearCorr_*BtoZcollinearCorr_);
- if (row==3 || row==9) result(row,col) = (WtoAcollinearCorr_*BtoZcollinearCorr_);
- if (row==4 || row==10) result(row,col) = (WtoZcollinearCorr_*BtoAcollinearCorr_);
- if (row==5 || row==11) result(row,col) = (WtoAcollinearCorr_*BtoAcollinearCorr_);
- if (row==12) result(row,col) = (WtoWcollinearCorr_*BtoZcollinearCorr_);
- if (row==13) result(row,col) = (WtoWcollinearCorr_*BtoAcollinearCorr_);
- if (row==18) result(row,col) = (WtoWcollinearCorr_*BtoZcollinearCorr_);
- if (row==19) result(row,col) = (WtoWcollinearCorr_*BtoAcollinearCorr_);
- }
- if (col==4) {
- if (row==2 || row==8) result(row,col) = (BtoZcollinearCorr_*BtoZcollinearCorr_);
- if (row==3 || row==4 || row==9 || row==10) result(row,col) = (BtoZcollinearCorr_*BtoAcollinearCorr_);
- if (row==5 || row==11) result(row,col) = (BtoAcollinearCorr_*BtoAcollinearCorr_);
- }
-
- // Particle Collinear Corr_ections:
- if (process==QQWW) {
- if (row<6) result(row,col) *= (ULcollinearCorr_*ULcollinearCorr_);
- if ((row>=6)&&(row<12)) result(row,col) *= (DLcollinearCorr_*DLcollinearCorr_);
- if (row>=12) result(row,col) *= (ULcollinearCorr_*DLcollinearCorr_);
- }
- else if (process==LLWW) {
- if (row<6) result(row,col) *= (nuLcollinearCorr_*nuLcollinearCorr_);
- if ((row>=6)&&(row<12)) result(row,col) *= (ELcollinearCorr_*ELcollinearCorr_);
- if (row>=12) result(row,col) *= (nuLcollinearCorr_*ELcollinearCorr_);
- }
- }
- }
- }
- break;
- case QQPhiPhi:
- case LLPhiPhi:
- {
- unsigned int numGauge = 2;
- unsigned int numBrokenGauge = 14;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- for (unsigned int row = 0; row < result.size1(); row++) {
-
- // Boson Colinear Corr_ections:
- if (row==0 || row==5) result(row,0) = (PhitoWcollinearCorr_*PhitoWcollinearCorr_);
- if (row==1 || row==6) result(row,0) = (PhitoZcollinearCorr_*PhitoZcollinearCorr_);
- if (row==2 || row==3 || row==7 || row==8) result(row,0) = (PhitoZcollinearCorr_*PhitoHcollinearCorr_);
- if (row==4 || row==9) result(row,0) = (PhitoHcollinearCorr_*PhitoHcollinearCorr_);
- if (row==10) result(row,0) = (PhitoWcollinearCorr_*PhitoZcollinearCorr_);
- if (row==11) result(row,0) = (PhitoWcollinearCorr_*PhitoHcollinearCorr_);
- if (row==12) result(row,0) = (PhitoWcollinearCorr_*PhitoZcollinearCorr_);
- if (row==13) result(row,0) = (PhitoWcollinearCorr_*PhitoHcollinearCorr_);
-
- // Particle Colinear Corr_ections:
- if (process==QQPhiPhi) {
- if (row<5) result(row,0) *= (ULcollinearCorr_*ULcollinearCorr_);
- if ((row>=5)&&(row<10)) result(row,0) *= (DLcollinearCorr_*DLcollinearCorr_);
- if (row>=10) result(row,0) *= (ULcollinearCorr_*DLcollinearCorr_);
- }
- else if (process==LLPhiPhi) {
- if (row<5) result(row,0) *= (nuLcollinearCorr_*nuLcollinearCorr_);
- if ((row>=5)&&(row<10)) result(row,0) *= (ELcollinearCorr_*ELcollinearCorr_);
- if (row>=10) result(row,0) *= (nuLcollinearCorr_*ELcollinearCorr_);
- }
- }
- DuplicateColumn0(result);
- }
- break;
- case QQWG:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 6;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(1,0) = ULcollinearCorr_*DLcollinearCorr_*GcollinearCorr_*WtoWcollinearCorr_;
- result(2,0) = ULcollinearCorr_*ULcollinearCorr_*GcollinearCorr_*WtoZcollinearCorr_;
- result(3,0) = ULcollinearCorr_*ULcollinearCorr_*GcollinearCorr_*WtoAcollinearCorr_;
- result(4,0) = DLcollinearCorr_*DLcollinearCorr_*GcollinearCorr_*WtoZcollinearCorr_;
- result(5,0) = DLcollinearCorr_*DLcollinearCorr_*GcollinearCorr_*WtoAcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case QQBG:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = ULcollinearCorr_*ULcollinearCorr_*GcollinearCorr_*BtoZcollinearCorr_;
- result(1,0) = ULcollinearCorr_*ULcollinearCorr_*GcollinearCorr_*BtoAcollinearCorr_;
- result(2,0) = DLcollinearCorr_*DLcollinearCorr_*GcollinearCorr_*BtoZcollinearCorr_;
- result(3,0) = DLcollinearCorr_*DLcollinearCorr_*GcollinearCorr_*BtoAcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case QQGG:
- {
- unsigned int numGauge = 3;
- unsigned int numBrokenGauge = 6;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(1,0) = result(2,0) = ULcollinearCorr_*ULcollinearCorr_*GcollinearCorr_*GcollinearCorr_;
- result(3,0) = result(4,0) = result(5,0) = DLcollinearCorr_*DLcollinearCorr_*GcollinearCorr_*GcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case QtQtGG:
- {
- unsigned int numGauge = 3;
- unsigned int numBrokenGauge = 6;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(1,0) = result(2,0) = tLcollinearCorr_*tLcollinearCorr_*GcollinearCorr_*GcollinearCorr_;
- result(3,0) = result(4,0) = result(5,0) = bLcollinearCorr_*bLcollinearCorr_*GcollinearCorr_*GcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case UUBB:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = URcollinearCorr_*URcollinearCorr_*BtoZcollinearCorr_*BtoZcollinearCorr_;
- result(1,0) = URcollinearCorr_*URcollinearCorr_*BtoZcollinearCorr_*BtoAcollinearCorr_;
- result(2,0) = URcollinearCorr_*URcollinearCorr_*BtoAcollinearCorr_*BtoZcollinearCorr_;
- result(3,0) = URcollinearCorr_*URcollinearCorr_*BtoAcollinearCorr_*BtoAcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case UUPhiPhi:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 5;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = URcollinearCorr_*URcollinearCorr_*PhitoWcollinearCorr_*PhitoWcollinearCorr_;
- result(1,0) = URcollinearCorr_*URcollinearCorr_*PhitoZcollinearCorr_*PhitoZcollinearCorr_;
- result(2,0) = URcollinearCorr_*URcollinearCorr_*PhitoHcollinearCorr_*PhitoZcollinearCorr_;
- result(3,0) = URcollinearCorr_*URcollinearCorr_*PhitoZcollinearCorr_*PhitoHcollinearCorr_;
- result(4,0) = URcollinearCorr_*URcollinearCorr_*PhitoHcollinearCorr_*PhitoHcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case UUBG:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = URcollinearCorr_*URcollinearCorr_*GcollinearCorr_*BtoZcollinearCorr_;
- result(1,0) = URcollinearCorr_*URcollinearCorr_*GcollinearCorr_*BtoAcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case UUGG:
- {
- unsigned int numGauge = 3;
- unsigned int numBrokenGauge = 3;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(1,0) = result(2,0) = URcollinearCorr_*URcollinearCorr_*GcollinearCorr_*GcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case tRtRGG:
- {
- unsigned int numGauge = 3;
- unsigned int numBrokenGauge = 3;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(1,0) = result(2,0) = tRcollinearCorr_*tRcollinearCorr_*GcollinearCorr_*GcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case DDBB:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = DRcollinearCorr_*DRcollinearCorr_*BtoZcollinearCorr_*BtoZcollinearCorr_;
- result(1,0) = DRcollinearCorr_*DRcollinearCorr_*BtoZcollinearCorr_*BtoAcollinearCorr_;
- result(2,0) = DRcollinearCorr_*DRcollinearCorr_*BtoAcollinearCorr_*BtoZcollinearCorr_;
- result(3,0) = DRcollinearCorr_*DRcollinearCorr_*BtoAcollinearCorr_*BtoAcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case DDPhiPhi:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 5;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = DRcollinearCorr_*DRcollinearCorr_*PhitoWcollinearCorr_*PhitoWcollinearCorr_;
- result(1,0) = DRcollinearCorr_*DRcollinearCorr_*PhitoZcollinearCorr_*PhitoZcollinearCorr_;
- result(2,0) = DRcollinearCorr_*DRcollinearCorr_*PhitoHcollinearCorr_*PhitoZcollinearCorr_;
- result(3,0) = DRcollinearCorr_*DRcollinearCorr_*PhitoZcollinearCorr_*PhitoHcollinearCorr_;
- result(4,0) = DRcollinearCorr_*DRcollinearCorr_*PhitoHcollinearCorr_*PhitoHcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case DDBG:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = DRcollinearCorr_*DRcollinearCorr_*GcollinearCorr_*BtoZcollinearCorr_;
- result(1,0) = DRcollinearCorr_*DRcollinearCorr_*GcollinearCorr_*BtoAcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case DDGG:
- {
- unsigned int numGauge = 3;
- unsigned int numBrokenGauge = 3;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = result(1,0) = result(2,0) = DRcollinearCorr_*DRcollinearCorr_*GcollinearCorr_*GcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case EEBB:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = ERcollinearCorr_*ERcollinearCorr_*BtoZcollinearCorr_*BtoZcollinearCorr_;
- result(1,0) = ERcollinearCorr_*ERcollinearCorr_*BtoZcollinearCorr_*BtoAcollinearCorr_;
- result(2,0) = ERcollinearCorr_*ERcollinearCorr_*BtoAcollinearCorr_*BtoZcollinearCorr_;
- result(3,0) = ERcollinearCorr_*ERcollinearCorr_*BtoAcollinearCorr_*BtoAcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- case EEPhiPhi:
- {
- unsigned int numGauge = 1;
- unsigned int numBrokenGauge = 5;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge); result *= 0.0;
- result(0,0) = ERcollinearCorr_*ERcollinearCorr_*PhitoWcollinearCorr_*PhitoWcollinearCorr_;
- result(1,0) = ERcollinearCorr_*ERcollinearCorr_*PhitoZcollinearCorr_*PhitoZcollinearCorr_;
- result(2,0) = ERcollinearCorr_*ERcollinearCorr_*PhitoHcollinearCorr_*PhitoZcollinearCorr_;
- result(3,0) = ERcollinearCorr_*ERcollinearCorr_*PhitoZcollinearCorr_*PhitoHcollinearCorr_;
- result(4,0) = ERcollinearCorr_*ERcollinearCorr_*PhitoHcollinearCorr_*PhitoHcollinearCorr_;
- DuplicateColumn0(result);
- }
- break;
- default:
- assert(false);
- }
-
- // This is done at the end instead of the beginning for result.size1() and cols()
- if (!oneLoop) {
- boost::numeric::ublas::matrix<Complex> OnesMatrix(result.size1(),result.size2());
- for (unsigned int i=0; i<OnesMatrix.size1(); i++) {
- for (unsigned int j=0; j<OnesMatrix.size2(); j++) {
- OnesMatrix(i,j) = 1.0;
- }
- }
- return OnesMatrix;
- }
-
- return result;
-}
-
-boost::numeric::ublas::matrix<Complex>
-CollinearSudakov::highEnergyRunning(Energy highScale, Energy EWScale, Energy2 s,
- Herwig::EWProcess::Process process,
- bool fixedOrder) {
- using namespace EWProcess;
- // perform the calculation
- evaluateHighScale(highScale,EWScale,s);
- Complex colW(highColW_);
- Complex colB(highColB_);
- Complex colG(highColG_);
- Complex colQ(highColQ_);
- Complex colQt(highColQt_);
- Complex colU(highColU_);
- Complex coltR(highColtR_);
- Complex colD(highColD_);
- Complex colL(highColL_);
- Complex colE(highColE_);
- Complex colPhi(highColPhi_);
- if (fixedOrder) {
- /* colX not necessarily positive for s = (1000TeV)^2 for the following:
- colW = log(colW.real());
- colB = log(colB.real());
- colPhi = log(colPhi.real());
- */
- colG = log(colG.real());
- colQ = log(colQ.real());
- colQt = log(colQt.real());
- colU = log(colU.real());
- coltR = log(coltR.real());
- colD = log(colD.real());
- colL = log(colL.real());
- colE = log(colE.real());
- }
- // set up the matrix
- boost::numeric::ublas::matrix<Complex> result;
- unsigned int numGauge(0);
- switch (process) {
-
- case QQQQ:
- case QQQQiden:
- case QtQtQQ:
- numGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (process!=QtQtQQ) {
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colQ+colQ+colQ+colQ;
- }
- else {
- result(i,i) = colQ*colQ*colQ*colQ;
- }
- }
- }
- else {
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colQt+colQt+colQ+colQ;
- }
- else {
- result(i,i) = colQt*colQt*colQ*colQ;
- }
- }
- }
- break;
-
- case QQUU:
- case QtQtUU:
- case QQtRtR:
- numGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (process==QQUU) {
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colQ+colQ+colU+colU;
- }
- else {
- result(i,i) = colQ*colQ*colU*colU;
- }
- }
- }
- else if (process==QtQtUU) {
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colQt+colQt+colU+colU;
- }
- else {
- result(i,i) = colQt*colQt*colU*colU;
- }
- }
- }
- else if (process==QQtRtR) {
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colQ+colQ+coltR+coltR;
- }
- else {
- result(i,i) = colQ*colQ*coltR*coltR;
- }
- }
- }
- break;
-
- case QQDD:
- case QtQtDD:
- numGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (process==QQDD) {
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colQ+colQ+colD+colD;
- }
- else {
- result(i,i) = colQ*colQ*colD*colD;
- }
- }
- }
- else {
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colQt+colQt+colD+colD;
- }
- else {
- result(i,i) = colQt*colQt*colD*colD;
- }
- }
- }
- break;
-
- case QQLL:
- numGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colQ+colQ+colL+colL;
- }
- else {
- result(i,i) = colQ*colQ*colL*colL;
- }
- }
- break;
-
- case QQEE:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colQ+colQ+colE+colE;
- }
- else {
- result(i,i) = colQ*colQ*colE*colE;
- }
- }
- break;
-
- case UUUU:
- case UUUUiden:
- case tRtRUU:
- numGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (process!=tRtRUU) {
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colU+colU+colU+colU;
- }
- else {
- result(i,i) = colU*colU*colU*colU;
- }
- }
- }
- else {
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+coltR+coltR+colU+colU;
- }
- else {
- result(i,i) = coltR*coltR*colU*colU;
- }
- }
- }
- break;
-
- case UUDD:
- case tRtRDD:
- numGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (process==UUDD) {
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colU+colU+colD+colD;
- }
- else {
- result(i,i) = colU*colU*colD*colD;
- }
- }
- }
- else {
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+coltR+coltR+colD+colD;
- }
- else {
- result(i,i) = coltR*coltR*colD*colD;
- }
- }
- }
- break;
-
- case UULL:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colU+colU+colL+colL;
- }
- else {
- result(i,i) = colU*colU*colL*colL;
- }
- }
- break;
-
- case UUEE:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colU+colU+colE+colE;
- }
- else {
- result(i,i) = colU*colU*colE*colE;
- }
- }
- break;
-
- case DDDD:
- case DDDDiden:
- numGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colD+colD+colD+colD;
- }
- else {
- result(i,i) = colD*colD*colD*colD;
- }
- }
- break;
-
- case DDLL:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colD+colD+colL+colL;
- }
- else {
- result(i,i) = colD*colD*colL*colL;
- }
- }
- break;
-
- case DDEE:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colD+colD+colE+colE;
- }
- else {
- result(i,i) = colD*colD*colE*colE;
- }
- }
- break;
-
- case LLLL:
- case LLLLiden:
- numGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colL+colL+colL+colL;
- }
- else {
- result(i,i) = colL*colL*colL*colL;
- }
- }
- break;
-
- case LLEE:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colL+colL+colE+colE;
- }
- else {
- result(i,i) = colL*colL*colE*colE;
- }
- }
- break;
-
- case EEEE:
- case EEEEiden:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- for (unsigned int i=0; i<numGauge; i++) {
- if (fixedOrder) {
- result(i,i) = 1.0+colE+colE+colE+colE;
- }
- else {
- result(i,i) = colE*colE*colE*colE;
- }
- }
- break;
-
- case QQWW:
- numGauge = 5;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = result(1,1) = 1.0+colQ+colQ+colW+colW;
- result(2,2) = result(3,3) = 1.0+colQ+colQ+colW+colB;
- result(4,4) = 1.0+colQ+colQ+colB+colB;
- }
- else {
- result(0,0) = result(1,1) = colQ*colQ*colW*colW;
- result(2,2) = result(3,3) = colQ*colQ*colW*colB;
- result(4,4) = colQ*colQ*colB*colB;
- }
- break;
-
- case QQPhiPhi:
- numGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = result(1,1) = 1.0+colQ+colQ+colPhi+colPhi;
- }
- else {
- result(0,0) = result(1,1) = colQ*colQ*colPhi*colPhi;
- }
- break;
-
- case QQWG:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = 1.0+colQ+colQ+colW+colG;
- }
- else {
- result(0,0) = colQ*colQ*colW*colG;
- }
- break;
-
- case QQBG:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = 1.0+colQ+colQ+colB+colG;
- }
- else {
- result(0,0) = colQ*colQ*colB*colG;
- }
- break;
-
- case QQGG:
- case QtQtGG:
- numGauge = 3;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (process==QQGG) {
- if (fixedOrder) {
- result(0,0) = result(1,1) = result(2,2) = 1.0+colQ+colQ+colG+colG;
- }
- else {
- result(0,0) = result(1,1) = result(2,2) = colQ*colQ*colG*colG;
- }
- }
- else {
- if (fixedOrder) {
- result(0,0) = result(1,1) = result(2,2) = 1.0+colQt+colQt+colG+colG;
- }
- else {
- result(0,0) = result(1,1) = result(2,2) = colQt*colQt*colG*colG;
- }
- }
- break;
-
- case LLWW:
- numGauge = 5;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = result(1,1) = 1.0+colL+colL+colW+colW;
- result(2,2) = result(3,3) = 1.0+colL+colL+colW+colB;
- result(4,4) = 1.0+colL+colL+colB+colB;
- }
- else {
- result(0,0) = result(1,1) = colL*colL*colW*colW;
- result(2,2) = result(3,3) = colL*colL*colW*colB;
- result(4,4) = colL*colL*colB*colB;
- }
- break;
-
- case LLPhiPhi:
- numGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = result(1,1) = 1.0+colL+colL+colPhi+colPhi;
- }
- else {
- result(0,0) = result(1,1) = colL*colL*colPhi*colPhi;
- }
- break;
-
- case UUBB:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = 1.0+colU+colU+colB+colB;
- }
- else {
- result(0,0) = colU*colU*colB*colB;
- }
- break;
-
- case UUPhiPhi:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = 1.0+colU+colU+colPhi+colPhi;
- }
- else {
- result(0,0) = colU*colU*colPhi*colPhi;
- }
- break;
-
- case UUBG:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = 1.0+colU+colU+colB+colG;
- }
- else {
- result(0,0) = colU*colU*colB*colG;
- }
- break;
-
- case UUGG:
- case tRtRGG:
- numGauge = 3;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (process==UUGG) {
- if (fixedOrder) {
- result(0,0) = result(1,1) = result(2,2) = 1.0+colU+colU+colG+colG;
- }
- else {
- result(0,0) = result(1,1) = result(2,2) = colU*colU*colG*colG;
- }
- }
- else {
- if (fixedOrder) {
- result(0,0) = result(1,1) = result(2,2) = 1.0+coltR+coltR+colG+colG;
- }
- else {
- result(0,0) = result(1,1) = result(2,2) = coltR*coltR*colG*colG;
- }
- }
- break;
-
- case DDBB:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = 1.0+colD+colD+colB+colB;
- }
- else {
- result(0,0) = colD*colD*colB*colB;
- }
- break;
-
- case DDPhiPhi:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = 1.0+colD+colD+colPhi+colPhi;
- }
- else {
- result(0,0) = colD*colD*colPhi*colPhi;
- }
- break;
-
- case DDBG:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = 1.0+colD+colD+colB+colG;
- }
- else {
- result(0,0) = colD*colD*colB*colG;
- }
- break;
-
- case DDGG:
- numGauge = 3;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = result(1,1) = result(2,2) = 1.0+colD+colD+colG+colG;
- }
- else {
- result(0,0) = result(1,1) = result(2,2) = colD*colD*colG*colG;
- }
- break;
-
- case EEBB:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = 1.0+colE+colE+colB+colB;
- }
- else {
- result(0,0) = colE*colE*colB*colB;
- }
- break;
-
- case EEPhiPhi:
- numGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- if (fixedOrder) {
- result(0,0) = 1.0+colE+colE+colPhi+colPhi;
- }
- else {
- result(0,0) = colE*colE*colPhi*colPhi;
- }
- break;
-
- default:
- assert(false);
- }
-
- return result;
-}
-
-boost::numeric::ublas::matrix<Complex>
-CollinearSudakov::lowEnergyRunning(Energy EWScale, Energy lowScale, Energy2 s,
- Herwig::EWProcess::Process process) {
- using namespace EWProcess;
- // evaluate the running
- evaluateLowScale(EWScale,lowScale,s);
-
- Complex colUL = lowColU_;
- Complex colDL = lowColD_;
- Complex colUR = lowColU_;
- Complex colDR = lowColD_;
-
- Complex coltL = lowColt_;
- Complex coltR = lowColt_;
- Complex colbL = lowColD_;
-
- Complex colnuL = 1.0;
- Complex colEL = lowColE_;
- Complex colER = lowColE_;
-
- Complex colW = lowColW_;
- Complex colZ = 1.0;
- Complex colA = lowColA_;
-
- Complex colPhi = lowColW_;
- Complex colPhi3 = 1.0;
- Complex colH = 1.0;
-
- Complex colG = lowColG_;
-
- // calculate the matrix
- boost::numeric::ublas::matrix<Complex> result;
- unsigned int numBrokenGauge;
- switch (process) {
- case QQQQ:
- case QQQQiden:
- numBrokenGauge = 12;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(6,6) = colUL*colUL*colUL*colUL;
- result(3,3) = result(9,9) = colDL*colDL*colDL*colDL;
- for (unsigned int i=0; i<12; i++) {
- if (i!=0 && i!=3 && i!=6 && i!=9) {
- result(i,i) = colUL*colUL*colDL*colDL;
- }
- }
- break;
- case QtQtQQ:
- numBrokenGauge = 12;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(6,6) = colUL*colUL*coltL*coltL;
- result(3,3) = result(9,9) = colDL*colDL*colbL*colbL;
- for (unsigned int i=0; i<12; i++) {
- if (i==4 || i==5 || i==10 || i==11) {
- result(i,i) = colUL*coltL*colDL*colbL;
- }
- else if (i==1 || i==7) {
- result(i,i) = colDL*colDL*coltL*coltL;
- }
- else if (i==2 || i==8) {
- result(i,i) = colUL*colUL*colbL*colbL;
- }
- }
- break;
- case QQUU:
- numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(2,2) = colUL*colUL*colUR*colUR;
- result(1,1) = result(3,3) = colDL*colDL*colUR*colUR;
- break;
- case QtQtUU:
- numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(2,2) = coltL*coltL*colUR*colUR;
- result(1,1) = result(3,3) = colbL*colbL*colUR*colUR;
- break;
- case QQtRtR:
- numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(2,2) = colUL*colUL*coltR*coltR;
- result(1,1) = result(3,3) = colDL*colDL*coltR*coltR;
- break;
- case QQDD:
- numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(2,2) = colUL*colUL*colDR*colDR;
- result(1,1) = result(3,3) = colDL*colDL*colDR*colDR;
- break;
- case QtQtDD:
- numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(2,2) = coltL*coltL*colDR*colDR;
- result(1,1) = result(3,3) = colbL*colbL*colDR*colDR;
- break;
- case QQLL:
- numBrokenGauge = 6;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colnuL*colnuL*colUL*colUL;
- result(1,1) = colnuL*colnuL*colDL*colDL;
- result(2,2) = colEL*colEL*colUL*colUL;
- result(3,3) = colEL*colEL*colDL*colDL;
- result(4,4) = result(5,5) = colnuL*colEL*colUL*colDL;
- break;
- case QQEE:
- numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colUL*colUL*colER*colER;
- result(1,1) = colDL*colDL*colER*colER;
- break;
- case UUUU:
- case UUUUiden:
- numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(1,1) = colUR*colUR*colUR*colUR;
- break;
- case tRtRUU:
- numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(1,1) = coltR*coltR*colUR*colUR;
- break;
- case UUDD:
- numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(1,1) = colUR*colUR*colDR*colDR;
- break;
- case tRtRDD:
- numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(1,1) = coltR*coltR*colDR*colDR;
- break;
- case UULL:
- numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colnuL*colnuL*colUR*colUR;
- result(1,1) = colEL*colEL*colUR*colUR;
- break;
- case UUEE:
- numBrokenGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colUR*colUR*colER*colER;
- break;
- case DDDD:
- case DDDDiden:
- numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(1,1) = colDR*colDR*colDR*colDR;
- break;
- case DDLL:
- numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colnuL*colnuL*colDR*colDR;
- result(1,1) = colEL*colEL*colDR*colDR;
- break;
- case DDEE:
- numBrokenGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colDR*colDR*colER*colER;
- break;
- case LLLL:
- case LLLLiden:
- numBrokenGauge = 6;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colnuL*colnuL*colnuL*colnuL;
- result(1,1) = colnuL*colnuL*colEL*colEL;
- result(2,2) = colEL*colEL*colnuL*colnuL;
- result(3,3) = colEL*colEL*colEL*colEL;
- result(4,4) = result(5,5) = colnuL*colEL*colnuL*colEL;
- break;
- case LLEE:
- numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colnuL*colnuL*colER*colER;
- result(1,1) = colEL*colEL*colER*colER;
- break;
- case EEEE:
- case EEEEiden:
- numBrokenGauge = 1;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colER*colER*colER*colER;
- break;
- case QQWW:
- case LLWW:
- numBrokenGauge = 20;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- for (unsigned int row = 0; row < result.size1(); row++) {
- // Boson Collinear Corrections:
- if (row==0 || row==1 || row==6 || row==7) result(row,row) = (colW*colW);
- else if (row==2 || row==8) result(row,row) = (colZ*colZ);
- else if (row==3 || row==4 || row==9 || row==10) result(row,row) = (colZ*colA);
- else if (row==5 || row==11) result(row,row) = (colA*colA);
- else if (row==12 || row==14) result(row,row) = (colW*colZ);
- else if (row==13 || row==15) result(row,row) = (colW*colA);
- else if (row==16 || row==18) result(row,row) = (colW*colZ);
- else if (row==17 || row==19) result(row,row) = (colW*colA);
-
- // Particle Collinear Corrections:
- if (process==QQWW) {
- if (row<6) result(row,row) *= (colUL*colUL);
- if ((row>=6)&&(row<12)) result(row,row) *= (colDL*colDL);
- if (row>=12) result(row,row) *= (colUL*colDL);
- }
- else if (process==LLWW) {
- if (row<6) result(row,row) *= (colnuL*colnuL);
- if ((row>=6)&&(row<12)) result(row,row) *= (colEL*colEL);
- if (row>=12) result(row,row) *= (colnuL*colEL);
- }
- }
- break;
- case QQPhiPhi:
- case LLPhiPhi:
- numBrokenGauge = 14;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- for (unsigned int row = 0; row < result.size1(); row++) {
-
- // Boson Colinear Corrections:
- if (row==0 || row==5) result(row,row) = (colPhi*colPhi);
- else if (row==1 || row==6) result(row,row) = (colPhi3*colPhi3);
- else if (row==2 || row==3 || row==7 || row==8) result(row,row) = (colPhi3*colH);
- else if (row==4 || row==9) result(row,row) = (colH*colH);
- else if (row==10) result(row,row) = (colPhi*colPhi3);
- else if (row==11) result(row,row) = (colPhi*colH);
- else if (row==12) result(row,row) = (colPhi*colPhi3);
- else if (row==13) result(row,row) = (colPhi*colH);
-
- // Particle Colinear Corrections:
- if (process==QQPhiPhi) {
- if (row<5) result(row,row) *= (colUL*colUL);
- if ((row>=5)&&(row<10)) result(row,row) *= (colDL*colDL);
- if (row>=10) result(row,row) *= (colUL*colDL);
- }
- else if (process==LLPhiPhi) {
- if (row<5) result(row,row) *= (colnuL*colnuL);
- if ((row>=5)&&(row<10)) result(row,row) *= (colEL*colEL);
- if (row>=10) result(row,row) *= (colnuL*colEL);
- }
- }
- break;
- case QQWG:
- numBrokenGauge = 6;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(1,1) = colUL*colDL*colG*colW;
- result(2,2) = colUL*colUL*colG*colZ;
- result(3,3) = colUL*colUL*colG*colA;
- result(4,4) = colDL*colDL*colG*colZ;
- result(5,5) = colDL*colDL*colG*colA;
- break;
- case QQBG:
- numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colUL*colUL*colG*colZ;
- result(1,1) = colUL*colUL*colG*colA;
- result(2,2) = colDL*colDL*colG*colZ;
- result(3,3) = colDL*colDL*colG*colA;
- break;
- case QQGG:
- numBrokenGauge = 6;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(1,1) = result(2,2) = colUL*colUL*colG*colG;
- result(3,3) = result(4,4) = result(5,5) = colDL*colDL*colG*colG;
- break;
- case QtQtGG:
- numBrokenGauge = 6;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(1,1) = result(2,2) = coltL*coltL*colG*colG;
- result(3,3) = result(4,4) = result(5,5) = colbL*colbL*colG*colG;
- break;
- case UUBB:
- numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colUR*colUR*colZ*colZ;
- result(1,1) = colUR*colUR*colZ*colA;
- result(2,2) = colUR*colUR*colA*colZ;
- result(3,3) = colUR*colUR*colA*colA;
- break;
- case UUPhiPhi:
- numBrokenGauge = 5;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colUR*colUR*colPhi*colPhi;
- result(1,1) = colUR*colUR*colPhi3*colPhi3;
- result(2,2) = colUR*colUR*colH*colPhi3;
- result(3,3) = colUR*colUR*colPhi3*colH;
- result(4,4) = colUR*colUR*colH*colH;
- break;
- case UUBG:
- numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colUR*colUR*colG*colZ;
- result(1,1) = colUR*colUR*colG*colA;
- break;
- case UUGG:
- numBrokenGauge = 3;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(1,1) = result(2,2) = colUR*colUR*colG*colG;
- break;
- case tRtRGG:
- numBrokenGauge = 3;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(1,1) = result(2,2) = coltR*coltR*colG*colG;
- break;
- case DDBB:
- numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colDR*colDR*colZ*colZ;
- result(1,1) = colDR*colDR*colZ*colA;
- result(2,2) = colDR*colDR*colA*colZ;
- result(3,3) = colDR*colDR*colA*colA;
- break;
- case DDPhiPhi:
- numBrokenGauge = 5;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colDR*colDR*colPhi*colPhi;
- result(1,1) = colDR*colDR*colPhi3*colPhi3;
- result(2,2) = colDR*colDR*colH*colPhi3;
- result(3,3) = colDR*colDR*colPhi3*colH;
- result(4,4) = colDR*colDR*colH*colH;
- break;
- case DDBG:
- numBrokenGauge = 2;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colDR*colDR*colG*colZ;
- result(1,1) = colDR*colDR*colG*colA;
- break;
-
- case DDGG:
- numBrokenGauge = 3;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = result(1,1) = result(2,2) = colDR*colDR*colG*colG;
- break;
- case EEBB:
- numBrokenGauge = 4;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colER*colER*colZ*colZ;
- result(1,1) = colER*colER*colZ*colA;
- result(2,2) = colER*colER*colA*colZ;
- result(3,3) = colER*colER*colA*colA;
- break;
- case EEPhiPhi:
- numBrokenGauge = 5;
- result = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- result(0,0) = colER*colER*colPhi*colPhi;
- result(1,1) = colER*colER*colPhi3*colPhi3;
- result(2,2) = colER*colER*colH*colPhi3;
- result(3,3) = colER*colER*colPhi3*colH;
- result(4,4) = colER*colER*colH*colH;
- break;
- default:
- assert(false);
- }
- return result;
-}
-
-
-
-
diff --git a/MatrixElement/EW/CollinearSudakov.fh b/MatrixElement/EW/CollinearSudakov.fh
deleted file mode 100644
--- a/MatrixElement/EW/CollinearSudakov.fh
+++ /dev/null
@@ -1,18 +0,0 @@
-// -*- C++ -*-
-//
-// This is the forward declaration of the CollinearSudakov class.
-//
-#ifndef Herwig_CollinearSudakov_FH
-#define Herwig_CollinearSudakov_FH
-
-#include "ThePEG/Config/ThePEG.h"
-
-namespace Herwig {
-
-class CollinearSudakov;
-
-ThePEG_DECLARE_POINTERS(Herwig::CollinearSudakov,CollinearSudakovPtr);
-
-}
-
-#endif
diff --git a/MatrixElement/EW/CollinearSudakov.h b/MatrixElement/EW/CollinearSudakov.h
deleted file mode 100644
--- a/MatrixElement/EW/CollinearSudakov.h
+++ /dev/null
@@ -1,546 +0,0 @@
-// -*- C++ -*-
-#ifndef Herwig_CollinearSudakov_H
-#define Herwig_CollinearSudakov_H
-//
-// This is the declaration of the CollinearSudakov class.
-//
-
-#include "ThePEG/Interface/Interfaced.h"
-#include "Herwig/Utilities/GSLIntegrator.h"
-// work around a Boost 1.64 bug where ublas headers would fail otherwise
-#include <boost/version.hpp>
-#if (BOOST_VERSION / 100 >= 1064)
-#include <boost/serialization/array_wrapper.hpp>
-#endif
-#include <boost/numeric/ublas/matrix.hpp>
-#include "EWProcess.h"
-#include "CollinearSudakov.fh"
-
-namespace Herwig {
-
-using namespace ThePEG;
-
-/**
- * Struct for the wavefunction corrections
- */
-struct WaveFunctionCorrections {
- Complex RW;
- Complex RA;
- Complex RZ;
- Complex RAtoZ;
- Complex RZtoA;
- Complex RPhi;
- Complex EW;
- Complex EZ;
- Complex RPhi3;
- Complex RH;
- Complex tLuLDiff;
- Complex bLdLDiff;
- Complex tRuRDiff;
-
- // The following are constants from parameter integrals:
-
- Complex fFW0;
- Complex fF0W;
- Complex fFZZ;
- Complex aHH;
- Complex aZZ;
- Complex aW0;
- Complex a0W;
- Complex bHH;
- Complex bZZ;
- Complex cHH;
- Complex cZZ;
- Complex cW0;
- Complex atHH;
- Complex atZZ;
- Complex atW0;
- Complex at0W;
- Complex ctHH;
- Complex ctZZ;
- Complex ctW0;
- Complex btHH;
- Complex btZZ;
-
- Complex fs10;
- Complex fs1ZW;
- Complex fsWZWZ;
- Complex fsZW1;
- Complex fs01;
- Complex fsHW1;
- Complex fsHZ1;
- Complex fs1HW;
- Complex fs1HZ;
-};
-
-/**
- * Here is the documentation of the CollinearSudakov class.
- *
- * @see \ref CollinearSudakovInterfaces "The interfaces"
- * defined for CollinearSudakov.
- */
-class CollinearSudakov: public Interfaced {
-
-public:
-
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- CollinearSudakov();
-
- /**
- * The destructor.
- */
- virtual ~CollinearSudakov();
- //@}
-
-public:
-
- /**
- * Evalaute the electroweak matching as a matrix
- */
- boost::numeric::ublas::matrix<Complex>
- electroWeakMatching(Energy EWScale, Energy2 s,
- Herwig::EWProcess::Process process,
- bool oneLoop);
-
- /**
- * Evalaute the high energy running as a matrix
- */
- boost::numeric::ublas::matrix<Complex>
- highEnergyRunning(Energy highScale, Energy EWScale, Energy2 s,
- Herwig::EWProcess::Process process,
- bool fixedOrder);
-
- /**
- * Evaluate the low energy running as a matrix
- */
- boost::numeric::ublas::matrix<Complex>
- lowEnergyRunning(Energy EWScale, Energy lowScale, Energy2 s,
- Herwig::EWProcess::Process process);
-public:
-
- /**
- * Make plots for tests
- */
- void makePlots();
-
-protected:
-
- /**
- * Evaluate the high scale contributions
- */
- void evaluateHighScale(Energy highScale, Energy EWScale, Energy2 S);
-
- /**
- * Evaluate the low scale contributions
- */
- void evaluateLowScale(Energy EWScale, Energy lowScale, Energy2 S);
-
- /**
- * Evaluate the matching
- */
- void evaluateMatching(Energy EWScale,Energy2 S);
-
-public:
-
- /**
- * The operator to be integrated
- */
- InvEnergy operator ()(Energy mu) const {
- if(high_) return highScaleIntegrand(mu);
- else return lowScaleIntegrand(mu);
- }
- /** Argument type for GaussianIntegrator */
- typedef Energy ArgType;
- /** Return type for GaussianIntegrator */
- typedef InvEnergy ValType;
-
-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:
-
- /**
- * The integral of the high scale part of the Sudakov
- */
- Complex highScaleIntegral(bool SU3, bool SU2, double Y,
- Energy2 s, Energy mu_h, Energy mu_l, bool fermion,
- bool longitudinal, double yukFactor);
-
- /**
- * the integral of the low scale part of the Sudakov
- */
- Complex lowScaleIntegral(bool SU3, double Q, Energy2 s,
- Energy mu_h, Energy mu_l, bool fermion,
- double boostFactor);
-
-protected:
-
- /**
- * High-scale integrand
- */
- InvEnergy highScaleIntegrand(Energy mu) const;
-
- /**
- * Low-scale integrand
- */
- InvEnergy lowScaleIntegrand(Energy mu) const;
-
- /**
- * Calculate the wavefunction corrections
- */
- WaveFunctionCorrections waveFunctionCorrections(Energy EWScale);
-
- /**
- * Collinear matiching for W
- */
- Complex CollinearDw(Energy2 s, Energy EWScale);
-
- /**
- * Collinear matching for Z
- */
- Complex CollinearDz(Energy2 s, Energy EWScale);
-
-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.
- */
- CollinearSudakov & operator=(const CollinearSudakov &) = delete;
-private:
-
- /**
- * Parameters for the integrand
- */
- //@{
- /**
- * Whether high or low scale
- */
- bool high_;
-
- /**
- * Whether real of imaginary part
- */
- bool real_;
-
- /**
- * \f$SU(3)\f$
- */
- bool SU3_;
-
- /**
- *
- */
- bool SU2_;
-
- /**
- *
- */
- double Y_;
-
- /**
- *
- */
- Energy2 s_;
-
- /**
- *
- */
- bool fermion_;
-
- /**
- *
- */
- bool longitudinal_;
-
- /**
- *
- */
- double yukFactor_;
-
- /**
- *
- */
- double boostFactor_;
-
- /**
- *
- */
- double Q_;
- //@}
-
- /**
- * Parameters
- */
- //@{
- /**
- * Order for the K terms
- */
- int K_ORDER_;
-
- /**
- * Order for the B terms
- */
- int B_ORDER_;
- //@}
-
- /**
- * Integrator
- */
- GSLIntegrator integrator_;
-
-private:
-
- /**
- * Storage of the high scale pieces
- */
- //@{
- /**
- *
- */
- Complex highColW_;
-
- /**
- *
- */
- Complex highColB_;
-
- /**
- *
- */
- Complex highColG_;
-
- /**
- *
- */
- Complex highColQ_;
-
- /**
- *
- */
- Complex highColQt_;
-
- /**
- *
- */
- Complex highColU_;
-
- /**
- *
- */
- Complex highColtR_;
-
- /**
- *
- */
- Complex highColD_;
-
- /**
- *
- */
- Complex highColL_;
-
- /**
- *
- */
- Complex highColE_;
-
- /**
- *
- */
- Complex highColPhi_;
- //@}
-
- /**
- * Storage of the low scale pieces
- */
- //@{
- /**
- *
- */
- complex<double> lowColW_;
-
- /**
- *
- */
- Complex lowColA_;
-
- /**
- *
- */
- Complex lowColG_;
-
- /**
- *
- */
- Complex lowColU_;
-
- /**
- *
- */
- Complex lowColt_;
-
- /**
- *
- */
- Complex lowColD_;
-
- /**
- *
- */
- Complex lowColE_;
- //@}
-
- /**
- * Storage of the matching parameters
- */
- //@{
- /**
- *
- */
- Complex ULcollinearCorr_;
-
- /**
- *
- */
- Complex DLcollinearCorr_;
-
- /**
- *
- */
- Complex URcollinearCorr_;
-
- /**
- *
- */
- Complex DRcollinearCorr_;
-
- /**
- *
- */
- Complex tLcollinearCorr_;
-
- /**
- *
- */
- Complex tRcollinearCorr_;
-
- /**
- *
- */
- Complex bLcollinearCorr_;
-
- /**
- *
- */
- Complex nuLcollinearCorr_;
-
- /**
- *
- */
- Complex ELcollinearCorr_;
-
- /**
- *
- */
- Complex ERcollinearCorr_;
-
- /**
- *
- */
- Complex WtoWcollinearCorr_;
-
- /**
- *
- */
- Complex WtoZcollinearCorr_;
-
- /**
- *
- */
- Complex WtoAcollinearCorr_;
-
- /**
- *
- */
- Complex BtoZcollinearCorr_;
-
- /**
- *
- */
- Complex BtoAcollinearCorr_;
-
- /**
- *
- */
- Complex PhitoWcollinearCorr_;
-
- /**
- *
- */
- Complex PhitoZcollinearCorr_;
-
- /**
- *
- */
- Complex PhitoHcollinearCorr_;
-
- /**
- *
- */
- Complex GcollinearCorr_;
- //@}
-};
-
-}
-
-#endif /* Herwig_CollinearSudakov_H */
diff --git a/MatrixElement/EW/EWCouplings.cc b/MatrixElement/EW/EWCouplings.cc
deleted file mode 100644
--- a/MatrixElement/EW/EWCouplings.cc
+++ /dev/null
@@ -1,734 +0,0 @@
-// -*- C++ -*-
-//
-// This is the implementation of the non-inlined, non-templated member
-// functions of the EWCouplings class.
-//
-
-#include "EWCouplings.h"
-#include "ThePEG/Interface/ClassDocumentation.h"
-#include "ThePEG/Interface/Parameter.h"
-#include "ThePEG/Interface/Switch.h"
-#include "ThePEG/EventRecord/Particle.h"
-#include "ThePEG/Repository/UseRandom.h"
-#include "ThePEG/Repository/EventGenerator.h"
-#include "ThePEG/Utilities/DescribeClass.h"
-#include "ThePEG/Persistency/PersistentOStream.h"
-#include "ThePEG/Persistency/PersistentIStream.h"
-#include <boost/numeric/ublas/operation.hpp>
-
-using namespace Herwig;
-
-namespace {
-
-Complex trace(boost::numeric::ublas::matrix<Complex> M) {
- assert(M.size1()==M.size2());
- Complex output(0.);
- for(unsigned int ix=0;ix<M.size1();++ix)
- output += M(ix,ix);
- return output;
-}
-}
-
-
-EWCouplings::EWCouplings(unsigned int loops, unsigned int steps,
- Energy lowScale)
- : ewScale_(91.1876*GeV), highScale_(14.*TeV), lowScale_(lowScale),
- includeSU3_(true), includeEW_(true), initialized_(false), massChoice_(false),
- mZ_(91.1876*GeV), mW_(80.399*GeV),
- mT_(173.1*GeV), // 179.08045 (should be this?)
- mH_(125.0*GeV),
- loops_(loops), highSteps_(steps), lowSteps_(steps),
- a1MZ_(0.01017054),a2MZ_(0.03378168),aSMZ_(0.1176),lambdat_(0.991172)
-{}
-
-void EWCouplings::initialize() {
- using Constants::pi;
- if(initialized_) return;
- initialized_ = true;
- highScale_=generator()->maximumCMEnergy();
- // set the particle masses
- if(massChoice_) {
- mZ_ = getParticleData(ParticleID::Z0 )->mass();
- mW_ = getParticleData(ParticleID::Wplus)->mass();
- mT_ = getParticleData(ParticleID::t )->mass();
- mH_ = getParticleData(ParticleID::h0 )->mass();
- }
- // logs of scales
- double logEWScale = log(ewScale_/GeV);
- double logHighScale = log(highScale_/GeV);
- // step size
- double stepsize = (logHighScale - logEWScale)/double(highSteps_);
- // Initialize parameters at the ewScale
- // 32 parameters, mostly zero due massless quarks
- unsigned int N = 32;
- vector<Complex> y(N,0.), dydx(N,0.), yout(N,0.);
- initializeCouplings(y);
- double x = logEWScale;
- derivatives(x,y,dydx);
- // energy scale + 6 parameters: g1,g2,g3,y_t,lambda,vev
- table_ = boost::numeric::ublas::matrix<double>(highSteps_+1,7);
- table_(0,0) = logEWScale;
- for (unsigned int i=1; i<N; i++) {
- if (i <=3) table_(0,i ) = (y[i-1].real()*y[i-1].real())/(4.0*pi);
- if (i >=29) table_(0,i-25) = y[i].real();
- }
- int counter = 1;
-
- // Use 4th order runge-kutta to integrate to highScale
- int steps = highSteps_;
- while (steps > 0) {
- RK4(y,dydx,x,stepsize,yout);
-
- // Advance x and calculate derivatives at new starting point
- for(unsigned int j=0; j<N; j++) {
- y[j] = yout[j];
- }
- x += stepsize;
- derivatives(x,y,dydx);
-
- table_(counter,0) = x;
- for (unsigned int i=1; i<N; i++) {
- if (i<=3 ) table_(counter,i ) = (y[i-1].real()*y[i-1].real())/(4.0*pi);
- if (i>=29) table_(counter,i-25) = y[i].real();
- }
-
- steps--;
- counter++;
- }
- // Initialize couplings at mu < 91.1876 GeV
- initializeLow();
-}
-
-EWCouplings::~EWCouplings() {}
-
-IBPtr EWCouplings::clone() const {
- return new_ptr(*this);
-}
-
-IBPtr EWCouplings::fullclone() const {
- return new_ptr(*this);
-}
-
-void EWCouplings::persistentOutput(PersistentOStream & os) const {
- os << ounit(ewScale_,GeV) << ounit(highScale_,GeV) << ounit(lowScale_,GeV)
- << includeSU3_ << includeEW_ << ounit(mZ_,GeV) << ounit(mW_,GeV)
- << ounit(mT_,GeV) << ounit(mH_,GeV) << massChoice_ << initialized_
- << loops_ << highSteps_ << lowSteps_
- << a1MZ_ << a2MZ_ << aSMZ_ << lambdat_;
- os << table_.size1() << table_.size2();
- for(unsigned int ix=0;ix<table_.size1();++ix)
- for(unsigned int iy=0;iy<table_.size2();++iy)
- os << table_(ix,iy);
- os << lowTable_.size1() << lowTable_.size2();
- for(unsigned int ix=0;ix<lowTable_.size1();++ix)
- for(unsigned int iy=0;iy<lowTable_.size2();++iy)
- os << lowTable_(ix,iy);
-}
-
-void EWCouplings::persistentInput(PersistentIStream & is, int) {
- is >> iunit(ewScale_,GeV) >> iunit(highScale_,GeV) >> iunit(lowScale_,GeV)
- >> includeSU3_ >> includeEW_ >> iunit(mZ_,GeV) >> iunit(mW_,GeV)
- >> iunit(mT_,GeV) >> iunit(mH_,GeV) >> massChoice_ >> initialized_
- >> loops_ >> highSteps_ >> lowSteps_
- >> a1MZ_ >> a2MZ_ >> aSMZ_ >> lambdat_;
- unsigned int size1,size2;
- is >> size1 >> size2;
- table_.resize(size1,size2);
- for(unsigned int ix=0;ix<table_.size1();++ix)
- for(unsigned int iy=0;iy<table_.size2();++iy)
- is >> table_(ix,iy);
- is >> size1 >> size2;
- lowTable_.resize(size1,size2);
- for(unsigned int ix=0;ix<lowTable_.size1();++ix)
- for(unsigned int iy=0;iy<lowTable_.size2();++iy)
- is >> lowTable_(ix,iy);
-}
-
-
-//The following static variable is needed for the type
-// description system in ThePEG.
-DescribeClass<EWCouplings,Interfaced>
-describeHerwigEWCouplings("Herwig::EWCouplings", "HwMEEW.so");
-
-void EWCouplings::Init() {
-
- static ClassDocumentation<EWCouplings> documentation
- ("The EWCouplings class implements");
-
- static Switch<EWCouplings,bool> interfaceMassChoice
- ("MassChoice",
- "Where to get the SM particle masses from",
- &EWCouplings::massChoice_, false, false, false);
- static SwitchOption interfaceMassChoiceLocal
- (interfaceMassChoice,
- "Local",
- "Use local values",
- false);
- static SwitchOption interfaceMassChoiceParticleData
- (interfaceMassChoice,
- "ParticleData",
- "Get the values from the ParticleData object",
- true);
-
- static Parameter<EWCouplings,Energy> interfaceEWScale
- ("EWScale",
- "The electroweak scale for matching between high and low energy running",
- &EWCouplings::ewScale_, GeV, 91.1876*GeV, 10.0*GeV, 10000.0*GeV,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,Energy> interfaceLowScale
- ("LowScale",
- "The low energy scale at which to stop the running",
- &EWCouplings::lowScale_, GeV, 10.*GeV, 1.0*GeV, 100.0*GeV,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,Energy> interfacemZ
- ("mZ",
- "The mass of the Z boson",
- &EWCouplings::mZ_, 91.1876*GeV, 90.*GeV, 92.*GeV,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,Energy> interfacemW
- ("mW",
- "The mass of the W boson",
- &EWCouplings::mW_, 80.399*GeV, 75.*GeV, 85.*GeV,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,Energy> interfacemT
- ("mT",
- "The mass of the top quark",
- &EWCouplings::mT_, 173.1*GeV, 100.*GeV, 1000.*GeV,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,Energy> interfacemH
- ("mH",
- "The mass of the Higgs boson",
- &EWCouplings::mH_, 125.*GeV, 100.*GeV, 1000.*GeV,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,unsigned int> interfaceLoops
- ("Loops",
- "The number of loops",
- &EWCouplings::loops_, 2, 1, 3,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,unsigned int> interfaceHighSteps
- ("HighSteps",
- "The number of steps for the Runga-Kutta and interpolation of the couplings above mZ",
- &EWCouplings::highSteps_, 200, 10, 1000000,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,unsigned int> interfaceLowSteps
- ("LowSteps",
- "The number of steps for the Runga-Kutta and interpolation of the couplings below mZ",
- &EWCouplings::lowSteps_, 200, 10, 1000000,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,double> interfacea1MZ
- ("Alpha1MZ",
- "The value of a1(MZ)",
- &EWCouplings::a1MZ_, 0.01017054, 0.0, 1.,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,double> interfacea2MZ
- ("Alpha2MZ",
- "The value of a2(MZ)",
- &EWCouplings::a2MZ_, 0.03378168, 0.0, 1.,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,double> interfaceasMZ
- ("AlphasMZ",
- "The value of as(MZ)",
- &EWCouplings::aSMZ_, 0.1176, 0.0, 1.,
- false, false, Interface::limited);
-
- static Parameter<EWCouplings,double> interfaceLambdaT
- ("LambdaT",
- "The top quark Yukawa at the matching scale",
- &EWCouplings::lambdat_, 0.991172, 0.5, 2.0,
- false, false, Interface::limited);
-
-}
-
-
-
-void EWCouplings::initializeLow() {
- using Constants::pi;
- // For scales less than ewScale, the only couplings calculated here are those of
- // alpha_EW and alpha3:
-
- double logEWScale = log(ewScale_ /GeV);
- double loglowScale = log(lowScale_/GeV);
-
- double stepsize = (loglowScale - logEWScale)/double(lowSteps_);
- int steps = lowSteps_;
-
- // Initialize parameters at the ewScale
- unsigned int N=2; // Total # of parameters = 2
- vector<Complex> y(N), dydx(N), yout(N);
- for (unsigned int i=0; i<N; i++) {
- y[i] = 0.0;
- dydx[i] = 0.0;
- yout[i] = 0.0;
- }
- double x = logEWScale;
-
- // Initialize Couplings at the ewScale, including the One-Loop Threshold Matching:
- double a1 = (3.0/5.0)*table_(0,1);
- double a2 = table_(0,2);
- double a3 = table_(0,3);
- double aEM_ewScale = 1./(1./a1+1./a2-1./(6.*pi)*(1.-21.*log(mW()/ewScale_)+16./3.*log(mTatmZ()/ewScale_)));
- double aS_ewScale = 1./(1./a3+1./(3.*pi)*log(ewScale_/mTatmZ()));
- y[0] = sqrt(4.0*pi*aEM_ewScale);
- y[1] = sqrt(4.0*pi*aS_ewScale);
-
- derivatives(x,y,dydx);
- // energy scale + 2 parameters: gEM,g3
- lowTable_.resize(lowSteps_+1,3);
- lowTable_(0,0) = logEWScale;
- for (unsigned int i=1; i<=N; i++) {
- lowTable_(0,i) = (y[i-1].real()*y[i-1].real())/(4.0*pi);
- }
- int counter = 1;
-
- // Use 4th order runge-kutta to integrate to highScale
- while (steps > 0) {
- RK4(y,dydx,x,stepsize,yout);
- // Advance x and calculate derivatives at new starting point
- for(unsigned int j=0; j<N; j++) {
- y[j] = yout[j];
- }
- x += stepsize;
- derivatives(x,y,dydx);
- lowTable_(counter,0) = x;
- for (unsigned int i=1; i<=N; i++) {
- lowTable_(counter,i) = (y[i-1].real()*y[i-1].real())/(4.0*pi);
- }
-
- steps--;
- counter++;
- }
-}
-
-void EWCouplings::RK4(vector<Complex> &y, vector<Complex> &dydx,
- const double x, const double h, vector<Complex> &yout) {
-
- unsigned int n = y.size();
- std::vector<Complex> dym(n), dyt(n), yt(n);
- double hh = h*0.5;
- double h6 = h/6.0;
- double xh = x + hh;
- const Complex I(0,1.0);
-
- for(unsigned int i=0; i<n; i++) yt[i] = y[i] + hh*dydx[i];
- derivatives(xh, yt, dyt);
- for(unsigned int i=0; i<n; i++) yt[i] = y[i] + hh*dyt[i];
- derivatives(xh, yt, dym);
- for(unsigned int i=0; i<n; i++) {
- yt[i] = y[i] + h*dym[i];
- dym[i] += dyt[i];
- }
- derivatives(x+h, yt, dyt);
- for(unsigned int i=0; i<n; i++) {
- yout[i] = y[i] + h6*(dydx[i] + dyt[i] + 2.0*dym[i]);
- }
-}
-
-
-void EWCouplings::initializeCouplings(vector<Complex> & y) {
- using Constants::pi;
- // \todo make these values parameters so they can be changed
- InvEnergy2 gFermi = 1.16637*pow(10.0,-5)/GeV2;
- Energy vev = 1.0/(sqrt(sqrt(2.0)*gFermi)); // vev = 246.221
-
- y[0] = sqrt(5./3.*4.*pi*a1MZ_); // g1 = Sqrt[5/3] * Sqrt[4*pi*a1]
- y[1] = sqrt(4.*pi*a2MZ_); // g2 = Sqrt[4*pi*a2]
- y[2] = sqrt(4.*pi*aSMZ_); // g3 = Sqrt[4*pi*as]
- // Note lambda_t = sqrt(2.0)*mt/vev only valid for mt(mt); need mt(mZ) here
- // Top Yukawa lambda from Manohar
- //Complex lambda_t = 1.02858;
- // Top Yukawa lambda from Sascha
- double lambda_t =lambdat_;
- // Quartic coupling lambda (need to multiply by a factor of 2 when accessing the quartic coupling)
- double lambda = (mH_/vev)*(mH_/vev);
- y[29] = lambda_t;
- y[30] = lambda;
- y[31] = vev/GeV;
-}
-
-void EWCouplings::derivatives(const double x, vector<Complex> & y,
- vector<Complex> &dydx) {
- // zero the output
- for (unsigned int i=0; i<dydx.size(); i++) dydx[i]=0.0;
- // low scale
- if (y.size()==2) {
- lowBetaGauge(x,y,dydx);
- }
- // high scale
- else {
- betaGauge(x,y,dydx);
- betaYukawa(x,y,dydx);
- betaHiggs(x,y,dydx);
- }
-}
-
-void EWCouplings::betaGauge(const double x, vector<Complex> &y, vector<Complex> & dydx) {
- using Constants::pi;
- using boost::numeric::ublas::axpy_prod;
- using boost::numeric::ublas::herm;
- const Complex I(0,1.0);
- // Yukawa
- boost::numeric::ublas::matrix<Complex> Yuk_u(3,3), Yuk_d(3,3), Yuk_e(3,3);
- for(unsigned int ix=0;ix<3;++ix) {
- for(unsigned int iy=0;iy<3;++iy) {
- Yuk_u(ix,iy) = y[21+3*ix+iy];
- Yuk_d(ix,iy) = y[12+3*ix+iy];
- Yuk_e(ix,iy) = y[ 3+3*ix+iy];
- }
- }
- // gauge
- boost::numeric::ublas::vector<Complex> gauge(3);
- for(unsigned int l=0; l<3; l++) gauge[l] = y[l];
- // Evaluate beta functions for gauge couplings
- double Ng = 0.5*numberOfFlavours(x);
- boost::numeric::ublas::vector<Complex> b(3), g2(3), gc(3), Cu(3), Cd(3), Ce(3);
- boost::numeric::ublas::matrix<Complex> B1(3,3),B2(3,3), B3(3,3), B(3,3);
- b[0] = -4.0/3.0*Ng - 1.0/10.0;
- b[1] = 22.0/3.0 - 4.0/3.0*Ng - 1.0/6.0;
- b[2] = 11.0 - 4.0/3.0*Ng;
- for(unsigned int ix=0;ix<3;++ix) {
- for(unsigned int iy=0;iy<3;++iy) {
- B1(ix,iy) = 0.;
- B2(ix,iy) = 0.;
- B3(ix,iy) = 0.;
- }
- }
- B1(1,1) = 136.0/3.0;
- B1(2,2) = 102.0;
- B2(0,0) = 19.0/15.0;
- B2(0,1) = 1.0/5.0;
- B2(0,2) = 11.0/30.0;
- B2(1,0) = 3.0/5.0;
- B2(1,1) = 49.0/3.0;
- B2(1,2) = 3.0/2.0 ;
- B2(2,0) = 44.0/15.0;
- B2(2,1) = 4.0;
- B2(2,2) = 76.0/3.0;
- B3(0,0) = 9.0/50.0;
- B3(0,1) = 3.0/10.0;
- B3(1,0) = 9.0/10.0;
- B3(1,1) = 13.0/6.0;
- B = B1 - Ng*B2 - B3;
- Cu[0] = 17.0/10.0;
- Cu[1] = 3.0/2.0;
- Cu[2] = 2.0;
- Cd[0] = 1.0/2.0;
- Cd[1] = 3.0/2.0;
- Cd[2] = 2.0;
- Ce[0] = 3.0/2.0;
- Ce[1] = 1.0/2.0;
- Ce[2] = 0.0;
- for (int i=0; i<3; i++) {
- g2(i) = pow(gauge(i),2);
- }
- // gc = trans(g2) * B
- axpy_prod(g2, B, gc, true);
- // compute the answer
- if(loops_ >= 1) {
- for(int l=0; l<3; l++) {
- dydx[l] = -b(l)*pow(gauge(l),3)/(16.0*pow(pi,2));
- }
- if (loops_ >= 2) {
- boost::numeric::ublas::matrix<Complex> temp(3,3);
- axpy_prod(herm(Yuk_u),Yuk_u,temp);
- Complex tr1 = trace(temp);
- axpy_prod(herm(Yuk_d),Yuk_d,temp);
- Complex tr2 = trace(temp);
- axpy_prod(herm(Yuk_e),Yuk_e,temp);
- Complex tr3 = trace(temp);
- for(int l=0; l<3; l++) {
- dydx[l] += -pow(gauge(l),3)/pow(16.0*pow(pi,2),2)*
- (gc(l) + Cu(l)*tr1 + Cd(l)*tr2 + Ce(l)*tr3 );
- }
- }
- }
-}
-
-void EWCouplings::lowBetaGauge(const double, vector<Complex> &y,
- vector<Complex> &dydx) {
- using Constants::pi;
- const Complex I(0,1.0);
- Complex e = y[0], g3 = y[1];
- // Evaluate beta functions for gauge couplings
- double Nu = 2.0, Nd = 3.0, Nl = 3.0;
- if(loops_ >=1) {
- dydx[0] += (16.0/9.0*Nu + 4.0/9.0*Nd + 4.0/3.0*Nl)*pow(e,3)/pow(4.0*pi,2);
- dydx[1] += (2.0/3.0*(Nu+Nd)-11.0)*pow(g3,3)/pow(4.0*pi,2);
- // Note this also includes the three-loop contribution for alpha_3
- if (loops_ >= 2) {
- dydx[0] += (64.0/27.0*Nu+4.0/27.0*Nd+4.0*Nl)*pow(e,5)/pow(4.0*pi,4) +
- (64.0/9.0*Nu+16.0/9.0*Nd)*pow(e,3)*pow(g3,2)/pow(4.0*pi,4);
- dydx[1] += (38.0/3.0*(Nu+Nd)-102.0)*pow(g3,5)/pow(4.0*pi,4) +
- (8.0/9.0*Nu+2.0/9.0*Nd)*pow(g3,3)*pow(e,2)/pow(4.0*pi,4) +
- (5033.0/18.0*(Nu+Nd)-325.0/54.0*(Nu+Nd)*(Nu+Nd)-2857.0/2.0)*pow(g3,7)/pow(4.0*pi,6);
- }
- }
-}
-
-void EWCouplings::betaYukawa(const double x, vector< Complex > &y, vector<Complex > &dydx) {
- using Constants::pi;
- const Complex I(0,1.0);
- boost::numeric::ublas::identity_matrix<Complex> Id(3,3);
- // Yukawa
- boost::numeric::ublas::matrix<Complex> Yuk_u(3,3), Yuk_d(3,3), Yuk_e(3,3);
- for(unsigned int ix=0;ix<3;++ix) {
- for(unsigned int iy=0;iy<3;++iy) {
- Yuk_u(ix,iy) = y[21+3*ix+iy];
- Yuk_d(ix,iy) = y[12+3*ix+iy];
- Yuk_e(ix,iy) = y[ 3+3*ix+iy];
- }
- }
- // gauge
- double Ng = 0.5*numberOfFlavours(x);
- boost::numeric::ublas::vector<Complex> gauge(3);
- for(unsigned int l=0; l<3; l++) gauge[l] = y[l];
- Complex lambda = y[30];
- // traces of yukawa matrices
- boost::numeric::ublas::matrix<Complex> mTemp(3,3),MUU(3,3),MDD(3,3),MLL(3,3),
- MUU2(3,3),MDD2(3,3),MLL2(3,3),MUUDD(3,3),MDDUU(3,3);
- axpy_prod(herm(Yuk_u),Yuk_u,MUU);
- Complex trU = trace( MUU);
- axpy_prod(MUU,MUU,MUU2);
- Complex trUU = trace(MUU2);
- axpy_prod(herm(Yuk_d),Yuk_d,MDD);
- Complex trD = trace( MDD);
- axpy_prod(MDD,MDD,MDD2);
- Complex trDD = trace(MDD2);
- axpy_prod(MUU,MDD,MUUDD);
- Complex trUD = trace(MUUDD);
- axpy_prod(MDD,MUU,MDDUU);
- axpy_prod(herm(Yuk_e),Yuk_e,MLL);
- Complex trL = trace( MLL);
- axpy_prod(MLL,MLL,MLL2);
- Complex trLL = trace(MLL2);
- Complex g02 = sqr(gauge[0]);
- Complex g12 = sqr(gauge[1]);
- Complex g22 = sqr(gauge[2]);
- // Evaluate beta functions for yukawa couplings
- boost::numeric::ublas::zero_matrix<Complex> zero3x3(3,3);
- boost::numeric::ublas::matrix<Complex> dYuk_udx(zero3x3), dYuk_ddx(zero3x3), dYuk_edx(zero3x3), beta1_u(zero3x3),
- beta1_d(zero3x3), beta1_e(zero3x3), beta2_u(zero3x3), beta2_d(zero3x3), beta2_e(zero3x3);
- Complex Y2 = 3.0*trU+3.0*trD + trL;
- Complex Y4 = (17.0/20.0*g02 + 9.0/4.0*g12 + 8.0*g22)*trU +
- (1.0/4.0*g02 + 9.0/4.0*g12 + 8.0*g22)*trD + 3.0/4.0*(g02 + g12)*trL;
- Complex chi4 = 27.0/4.0*trUU + 27.0/4.0*trDD + 9.0/4.0*trLL - 6.0/4.0*trUD;
- if(loops_ >= 1) {
- beta1_u = 3.0/2.0*(MUU - MDD) + (Y2 - 17.0/20.0*g02 - 9.0/4.0*g12 - 8.0*g22)*Id;
- beta1_d = 3.0/2.0*(MDD - MUU) + (Y2 - 1.0/4.0*g02 - 9.0/4.0*g12 - 8.0*g22)*Id;
- beta1_e = 3.0/2.0*(MLL) + (Y2 - 9.0/4.0*g02 - 9.0/4.0*g12)*Id;
-
- axpy_prod(Yuk_u,beta1_u,mTemp);
- dYuk_udx += (1.0/(16.0*pow(pi,2)))*mTemp;
- axpy_prod(Yuk_d,beta1_d,mTemp);
- dYuk_ddx += (1.0/(16.0*pow(pi,2)))*mTemp;
- axpy_prod(Yuk_e,beta1_e,mTemp);
- dYuk_edx += (1.0/(16.0*pow(pi,2)))*mTemp;
-
- if (loops_ >= 2) {
- Complex l2=sqr(lambda);
- beta2_u = 3.0/2.0*MUU2 - MUUDD - 1.0/4.0*MDDUU + 11.0/4.0*MDD2 + Y2*(5.0/4.0*MDD - 9.0/4.0*MUU) +
- (-chi4 + 3.0/2.0*l2)*Id - 2.0*lambda*(3.0*MUU + MDD) +
- (223.0/80.0*g02 + 135.0/16.0*g12 + 16.0*g22)*(MUU) -
- (43.0/80.0*g02 - 9.0/16.0*g12 + 16.0*g22)*(MDD) + 5.0/2.0*Y4*Id +
- ((9.0/200.0 + 29.0/45.0*Ng)*pow(gauge[0],4) - 9.0/20.0*pow(gauge[0]*gauge[1],2) +
- 19.0/15.0*pow(gauge[0]*gauge[2],2) - (35.0/4.0 - Ng)*pow(gauge[1],4) + 9.0*pow(gauge[1]*gauge[2],2) -
- (404.0/3.0 - 80.0/9.0*Ng)*pow(gauge[2],4))*Id;
- beta2_d = 3.0/2.0*MDD2 - MDDUU - 1.0/4.0*MUUDD + 11.0/4.0*MUU2 + Y2*(5.0/4.0*MUU - 9.0/4.0*MDD) + (-chi4 + 3.0/2.0*l2)*Id - 2.0*lambda*(3.0*MDD + MUU) + (187.0/80.0*g02 + 135.0/16.0*g12 + 16.0*g22)*(MDD) - (79.0/80.0*g02 - 9.0/16.0*g12 + 16.0*g22)*(MUU) + 5.0/2.0*Y4*Id - ((29.0/200.0 + 1.0/45.0*Ng)*pow(gauge[0],4) - 27.0/20.0*pow(gauge[0]*gauge[1],2) + 31.0/15.0*pow(gauge[0]*gauge[2],2) - (35.0/4.0 - Ng)*pow(gauge[1],4) + 9.0*pow(gauge[1]*gauge[2],2) - (404.0/3.0 - 80.0/9.0*Ng)*pow(gauge[2],4))*Id;
- beta2_e = 3.0/2.0*MLL2 - 9.0/4.0*Y2*MLL + (-chi4 + 3.0/2.0*l2)*Id - 6.0*lambda*(MLL) + (387.0/80.0*g02 + 135.0/15.0*g12)*(MLL) + 5.0/2.0*Y4*Id + ((51.0/200.0 + 11.0/5.0*Ng)*pow(gauge[0],4) + 27.0/20.0*pow(gauge[0]*gauge[1],2) - (35.0/4.0 - Ng)*pow(gauge[1],4))*Id;
-
- axpy_prod(Yuk_u,beta2_u,mTemp);
- dYuk_udx += (1.0/pow(16.0*pow(pi,2),2))*mTemp;
- axpy_prod(Yuk_d,beta2_d,mTemp);
- dYuk_ddx += (1.0/pow(16.0*pow(pi,2),2))*mTemp;
- axpy_prod(Yuk_e,beta2_e,mTemp);
- dYuk_edx += (1.0/pow(16.0*pow(pi,2),2))*mTemp;
- }
- }
-
- boost::numeric::ublas::vector<Complex> temp(27);
-
- for(unsigned int ix=0;ix<3;++ix) {
- for(unsigned int iy=0;iy<3;++iy) {
- dydx[ 3+ix+3*iy] = dYuk_edx(ix,iy);
- dydx[12+ix+3*iy] = dYuk_ddx(ix,iy);
- dydx[21+ix+3*iy] = dYuk_udx(ix,iy);
- }
- }
-}
-
-void EWCouplings::betaHiggs(const double x, vector<Complex> &y,
- vector<Complex> &dydx) {
- using Constants::pi;
- const Complex I(0,1.0);
- double Ng = 0.5*numberOfFlavours(x);
- // Yukawa
- boost::numeric::ublas::matrix<Complex> Yuk_u(3,3), Yuk_d(3,3), Yuk_e(3,3);
- for(unsigned int ix=0;ix<3;++ix) {
- for(unsigned int iy=0;iy<3;++iy) {
- Yuk_u(ix,iy) = y[21+3*ix+iy];
- Yuk_d(ix,iy) = y[12+3*ix+iy];
- Yuk_e(ix,iy) = y[ 3+3*ix+iy];
- }
- }
- // gauge
- boost::numeric::ublas::vector<Complex> gauge(3);
- for(int l=0; l<3; l++) gauge(l) = y[l];
- Complex lambda = y[30];
- complex<Energy> vev = y[31]*GeV;
- // Evaluate beta functions for higgs coupling
- Complex beta1_lambda(0.), beta2_lambda(0.), gamma1_vev(0.), gamma2_vev(0.),
- Y2(0.), H(0.), Y4(0.), chi4(0.);
- // traces of yukawa matrices
- boost::numeric::ublas::matrix<Complex> temp(3,3),temp2(3,3),MUU(3,3),MDD(3,3),MLL(3,3);
- axpy_prod(herm(Yuk_u),Yuk_u,MUU);
- Complex trU = trace( MUU);
- axpy_prod(MUU,MUU,temp);
- Complex trUU = trace(temp);
- axpy_prod(MUU,temp,temp2);
- Complex trUUU = trace(temp2);
- axpy_prod(herm(Yuk_d),Yuk_d,MDD);
- Complex trD = trace( MDD);
- axpy_prod(MDD,MDD,temp);
- Complex trDD = trace(temp);
- axpy_prod(MDD,temp,temp2);
- Complex trDDD = trace(temp2);
- axpy_prod(MUU,MDD,temp);
- Complex trUD = trace(temp);
- axpy_prod(herm(Yuk_e),Yuk_e,MLL);
- Complex trL = trace( MLL);
- axpy_prod(MLL,MLL,temp);
- Complex trLL = trace(temp);
- axpy_prod(MLL,temp,temp2);
- Complex trLLL = trace(temp2);
- axpy_prod(MUU+MDD,MDD,temp);
- axpy_prod(MUU,temp,temp2);
- Complex trUUDD = trace(temp2);
-
- Complex g02 = sqr(gauge[0]);
- Complex g12 = sqr(gauge[1]);
- Complex g22 = sqr(gauge[2]);
- Complex g04 = sqr(g02);
- Complex g14 = sqr(g12);
- double pi2 = sqr(pi);
- Y2 = 3.0*trU+3.0*trD + trL;
- Y4 = (17.0/20.0*g02 + 9.0/4.0*g12 + 8.0*g22)*(trU) + (1.0/4.0*g02 + 9.0/4.0*g12 + 8.0*g22)*(trD) + 3.0/4.0*(g02 + g12)*(trL);
- chi4 = 27.0/4.0*trUU + 27.0/4.0*trDD + 9.0/4.0*trLL - 6.0/4.0*trUD;
- H = 3.0*trUU + 3.0*trDD + trLL;
-
- if(loops_ >= 1) {
- Complex l2=sqr(lambda);
- beta1_lambda = 12.0*l2 - (9.0/5.0*g02 + 9.0*g12)*lambda + 9.0/4.0*(3.0/25.0*g04+2.0/5.0*g02*g12 + g14) + 4.0*Y2*lambda - 4.0*H;
- gamma1_vev = 9.0/4.0*(1.0/5.0*g02+g12)-Y2;
-
- dydx[30] += 1.0/(16.0*pi2)*beta1_lambda;
- dydx[31] += vev/(16.0*pi2)*gamma1_vev/GeV;
-
- if (loops_ >= 2) {
- beta2_lambda = -78.0*lambda*l2 + 18.0*(3.0/5.0*g02 + 3.0*g12)*l2 -
- ( (313.0/8.0 - 10.0*Ng)*g14 - 117.0/20.0*g02*g12 + 9.0/25.0*(229.0/4.0+50.0/9.0*Ng)*g04 )*lambda +
- (497.0/8.0 - 8.0*Ng)*g14*g12 - 3.0/5.0*(97.0/24.0 + 8.0/3.0*Ng)*g02*g14 -
- 9.0/25.0*(239.0/24.0 + 40.0/9.0*Ng)*g04*g12 - 27.0/125.0*(59.0/24.0 + 40.0/9.0*Ng)*g04*g02 -
- 64.0*g22*(trUU + trDD) - 8.0/5.0*g02*(2.0*trUU - trDD + 3.0*trLL) - 3.0/2.0*g14*Y4 +
- 10.0*lambda*( (17.0/20.0*g02 + 9.0/4.0*g12 + 8.0*g22)*trU + (1.0/4.0*g02 + 9.0/4.0*g12 + 8.0*g22)*trD + 3.0/4.0*(g02 + g12)*trL ) +
- 3.0/5.0*g02*( (-57.0/10.0*g02 + 21.0*g12 )*trU + (3.0/2.0*g02 + 9.0*g12)*trD + (-15.0/2.0*g02 + 11.0*g12)*trL ) - 24.0*l2*Y2 - lambda*H +
- 6.0*lambda*trUD + 20.0*(3.0*trUUU + 3.0*trDDD + trLLL) - 12.0*trUUDD;
- gamma2_vev = -3.0/2.0*l2 - 5.0/2.0*Y4 + chi4 - 27.0/80.0*g02*g12 -
- (93.0/800.0 + 1.0/2.0*Ng)*g04 + (511.0/32.0 - 5.0/2.0*Ng)*g14;
-
- dydx[30] += 1.0/pow(16.0*pi2,2)*beta2_lambda;
- dydx[31] += vev/pow(16.0*pi2,2)*gamma2_vev/GeV;
- }
- }
-}
-
-double EWCouplings::interpolate(double t, int paramIndex) {
- double stepsize = table_(1,0)-table_(0,0);
- double tol = 0.001*stepsize;
-
- double logewScale = log(ewScale_/GeV);
- double loghighScale = log(highScale_/GeV);
-
- if (t<logewScale-tol || t>loghighScale+tol) {
- cerr << "Stepsize: " << stepsize << std::endl;
- cerr << "tol: " << tol << std::endl;
- cerr << "logewScale: " << logewScale << std::endl;
- cerr << "loghighScale: " << loghighScale << std::endl;
- cerr << "paramIndex: " << paramIndex << std::endl;
- cerr << "t: " << t << std::endl;
-
- cerr << "Couplings::_Interp(double t, int parmIndex) trying to obtain parameter ";
- cerr << "value outside the available range. Returning zero." << std::endl;
- assert(false);
- }
-
- // return value at EW scale
- if (abs(t-logewScale)<tol) return table_(0,paramIndex);
-
- // return value at high scale
- if (abs(t-loghighScale)<tol) {
- return table_(table_.size1()-1,paramIndex);
- }
-
- unsigned int numSteps = int((t-table_(0,0))/stepsize);
-
- // Linear Interpolation:
- double x1 = table_(numSteps,0);
- double y1 = table_(numSteps,paramIndex);
- double x2 = table_(numSteps+1,0);
- double y2 = table_(numSteps+1,paramIndex);
- return y1+((y2-y1)/(x2-x1))*(t-x1);
-}
-
-double EWCouplings::interpolateLow(double t, int paramIndex) {
- double stepsize = lowTable_(0,0)-lowTable_(1,0);
- double tol = 0.00001*stepsize;
-
- double logewScale = log(ewScale_ /GeV);
- double loglowScale = log(lowScale_/GeV);
-
- if (t<loglowScale-tol || t>logewScale+tol) {
- cerr<< "Couplings::_LowInterp(double t, int parmIndex) trying to obtain parameter ";
- cerr << "value outside the available range. Returning zero." << std::endl;
- assert(false);
- }
-
- if (abs(t-logewScale)<tol) {
- return lowTable_(0,paramIndex);
- }
-
- if (std::abs(t-loglowScale)<tol) {
- return lowTable_(lowTable_.size1()-1,paramIndex);
- }
-
- int numSteps = (int)((lowTable_(0,0)-t)/stepsize);
- // Linear Interpolation:
- double x1 = lowTable_(numSteps,0);
- double y1 = lowTable_(numSteps,paramIndex);
- double x2 = lowTable_(numSteps+1,0);
- double y2 = lowTable_(numSteps+1,paramIndex);
- return y1+((y2-y1)/(x2-x1))*(t-x1);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/MatrixElement/EW/EWCouplings.fh b/MatrixElement/EW/EWCouplings.fh
deleted file mode 100644
--- a/MatrixElement/EW/EWCouplings.fh
+++ /dev/null
@@ -1,18 +0,0 @@
-// -*- C++ -*-
-//
-// This is the forward declaration of the EWCouplings class.
-//
-#ifndef Herwig_EWCouplings_FH
-#define Herwig_EWCouplings_FH
-
-#include "ThePEG/Config/ThePEG.h"
-
-namespace Herwig {
-
-class EWCouplings;
-
-ThePEG_DECLARE_POINTERS(Herwig::EWCouplings,EWCouplingsPtr);
-
-}
-
-#endif
diff --git a/MatrixElement/EW/EWCouplings.h b/MatrixElement/EW/EWCouplings.h
deleted file mode 100644
--- a/MatrixElement/EW/EWCouplings.h
+++ /dev/null
@@ -1,478 +0,0 @@
-// -*- C++ -*-
-#ifndef Herwig_EWCouplings_H
-#define Herwig_EWCouplings_H
-//
-// This is the declaration of the EWCouplings class.
-//
-
-#include "ThePEG/Interface/Interfaced.h"
-// work around a Boost 1.64 bug where ublas headers would fail otherwise
-#include <boost/version.hpp>
-#if (BOOST_VERSION / 100 >= 1064)
-#include <boost/serialization/array_wrapper.hpp>
-#endif
-#include <boost/numeric/ublas/vector.hpp>
-#include <boost/numeric/ublas/matrix.hpp>
-#include "EWCouplings.fh"
-
-namespace Herwig {
-
-using namespace ThePEG;
-
-/**
- * Here is the documentation of the EWCouplings class.
- *
- * @see \ref EWCouplingsInterfaces "The interfaces"
- * defined for EWCouplings.
- */
-class EWCouplings: public Interfaced {
-
-public:
-
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- EWCouplings(unsigned int loops=2, unsigned int steps=200, Energy lowScale=10.*GeV);
-
- /**
- * The destructor.
- */
- virtual ~EWCouplings();
- //@}
-
- /**
- * Initialize the running couplings
- */
- void initialize();
-
- /**
- * Number of dynamical quarks at $\log\mu = x$ (in GeV)
- * N.B.Integrate out top quark at Mz, not at Mt.
- */
- unsigned int numberOfFlavours(double x) {
- return x >= std::log(ewScale_/GeV) ? 6 : 5;
- }
-
-public:
-
- /**
- * Set whether or not to include \f$SU(3)\f$ running
- */
- void SU3(bool includeSU3) {includeSU3_ = includeSU3;}
-
- /**
- * Whether or not to include \f$SU(3)\f$ running
- */
- bool SU3() { return includeSU3_;}
-
- /**
- * Set whether or not to include EW running
- */
- void EW(bool includeEW) {includeEW_ = includeEW;}
-
- /**
- * Whether or not to include EW running
- */
- bool EW() { return includeEW_;}
-
- /**
- * alpha for the U1 gauge coupling at energy mu (in GeV):
- */
- double a1(Energy mu) {
- if (includeEW_) {
- if (mu>=ewScale_) {
- return (3.0/5.0)*interpolate(log(mu/GeV),1);
- }
- return interpolateLow(log(mu/GeV),1);
- }
- else
- return 0.0;
- }
-
- /**
- * alpha for the SU2 gauge coupling at energy mu (in GeV):
- */
- double a2(Energy mu) {
- if (includeEW_) {
- if (mu<ewScale_) {
- return 0.0;
- }
- else
- return interpolate(log(mu/GeV),2);
- }
- else
- return 0.0;
- }
-
- /**
- * alpha for the SU3 gauge coupling at energy mu (in GeV):
- */
- double a3(Energy mu) {
- if(includeSU3_) {
- if (mu>=ewScale_) {
- return interpolate(log(mu/GeV),3);
- }
- else {
- return interpolateLow(log(mu/GeV),2);
- }
- }
- else
- return 0.0;
- }
-
- /**
- * alpha for EM
- */
- double aEM(Energy mu) {
- if (includeEW_) {
- if (mu<=ewScale_) {
- return interpolateLow(log(mu/GeV),1);
- }
- else {
- double alpha1=a1(mu);
- double alpha2=a2(mu);
- return alpha1*alpha2/(alpha1+alpha2);
- }
- }
- return 0.0;
- }
-
- double aS(Energy mu) {
- if(includeSU3_) {
- if (mu<=ewScale_) {
- return interpolateLow(log(mu/GeV),2);
- }
- else {
- return interpolate(log(mu/GeV),3);
- }
- }
- else return 0.0;
- }
-
- /**
- * Top quark Yukawa coupling
- */
- double y_t(Energy mu) {
- if (includeEW_) {
- if(mu<ewScale_)
- return 0.0;
- else
- return interpolate(log(mu/GeV),4);
- }
- else
- return 0.0;
- }
-
- /**
- * Quartic scalar coupling lambda (normalization different, hence factor of 2):
- */
- double lambda(Energy mu) {return 2.0*interpolate(log(mu/GeV),5);}
-
- /**
- * VEV
- */
- Energy vev(Energy mu) {return interpolate(log(mu/GeV),6)*GeV;}
-
- /**
- * \f$\lambda_t\f$
- */
- double lambda_t(Energy mu) {return y_t(mu);}
-
- /**
- * Z couplings
- */
- //@{
- double g_Lu(Energy mu) {return 0.5-(2.0/3.0)*Sin2thW(mu);}
- double g_Ld(Energy mu) {return -0.5+(1.0/3.0)*Sin2thW(mu);}
- double g_Le(Energy mu) {return (-1.0/2.0)+Sin2thW(mu);}
- double g_Lnu(Energy ) {return (0.5);}
- double g_Ru(Energy mu) {return (-2.0/3.0)*Sin2thW(mu);}
- double g_Rd(Energy mu) {return (1.0/3.0)*Sin2thW(mu);}
- double g_Re(Energy mu) {return Sin2thW(mu);}
- double g_W(Energy mu) {return Cos2thW(mu);}
- double g_phiPlus(Energy mu) {return 0.5-Sin2thW(mu);}
- //@}
-
- /**
- * \f\cos^2\theta_W\f$
- */
- double Cos2thW(Energy ) {
- //\todo why this value?
- //return mW()*mW()/(mZ()*mZ());
- return (1.-0.2314);
- }
-
- /**
- * \f\sin^2\theta_W\f$
- */
- double Sin2thW(Energy mu) {return 1.-Cos2thW(mu);}
-
- double aW(Energy mu) {return a2(mu);}
-
- double aZ(Energy mu) {
- //return a2(mu)/Cos2thW(mu); // Same thing, actually
- return a1(mu)+a2(mu);
- }
-
-public:
-
- /**
- * Masses of the Standard Model particles
- */
- //@{
- /**
- * Z mass
- */
- Energy mZ() const { return mZ_;}
-
- /**
- * W Mass
- */
- Energy mW() const { return mW_;}
-
- /**
- * Top quark mass
- */
- Energy mT() const {return mT_;}
-
- Energy mTatmZ() { return mT_;}
-
- /**
- * Higg boson mass
- */
- Energy mH() const {return mH_;}
- //@}
-
-public:
-
- /** @name Functions used by the persistent I/O system. */
- //@{
- /**
- * Function used to write out object persistently.
- * @param os the persistent output stream written to.
- */
- void persistentOutput(PersistentOStream & os) const;
-
- /**
- * Function used to read in object persistently.
- * @param is the persistent input stream read from.
- * @param version the version number of the object when written.
- */
- void persistentInput(PersistentIStream & is, int version);
- //@}
-
- /**
- * The standard Init function used to initialize the interfaces.
- * Called exactly once for each class by the class description system
- * before the main function starts or
- * when this class is dynamically loaded.
- */
- static void Init();
-
-protected:
-
- /** @name Clone Methods. */
- //@{
- /**
- * Make a simple clone of this object.
- * @return a pointer to the new object.
- */
- virtual IBPtr clone() const;
-
- /** Make a clone of this object, possibly modifying the cloned object
- * to make it sane.
- * @return a pointer to the new object.
- */
- virtual IBPtr fullclone() const;
- //@}
-
-private:
-
- /**
- * Set the initial value of the couplings
- */
- void initializeCouplings(vector<Complex> & y);
-
- /**
- * Assigns numerical values to beta functions
- * Takes in a point x = log(mu) and the values of y[i] at x and assigns dydx[i] the
- * value beta[i](mu). The function Derivs farms out the plugging in to the three
- * functions BetaGauge, BetaYukawa, and BetaHiggs, which evaluates the beta functions
- * for the gauge couplings, yukawa matrices, and higgs quartic coupling/vev, respectively.
- */
- void derivatives(const double x, vector< Complex > &y,
- vector< Complex > & dydx);
-
- /**
- * Beta function for the gauge interactions
- */
- void betaGauge(const double x, vector<Complex> &y, vector<Complex> &dydx);
-
- /**
- * Beta function for the gauge interactions at low scales
- */
- void lowBetaGauge(const double x, vector<Complex> &y, vector<Complex> &dydx);
-
- /**
- * Beta function for the Yukawa interactions
- */
- void betaYukawa(const double x, vector<Complex> &y, vector<Complex> &dydx);
-
- /**
- * Beta function for the Higgs interactions
- */
- void betaHiggs(const double x, vector<Complex> &y, vector<Complex> &dydx);
-
- /**
- * Update the couplings using 4-th order RK
- * Takes in a vector y[i] of function values at a point x and the values of the
- * first derivatives dydx[i] ( = dy[i]/dx ) alon with a step size stepsize. The
- * function then defines assigns the value of y[i](x+stepsize) to the variable yout[i].
- * (Adapted from sample code in Numerical Recipes in C++ Press, Teukolsky, et. al.)
- */
- void RK4(vector<Complex> & y, vector<Complex> &dydx, const double x,
- const double stepsize, vector<Complex> &yout);
-
- /**
- * Initialize the low energy parameters
- */
- void initializeLow();
-
- /**
- * Interpolate the table, t = ln(mu)
- */
- double interpolate(double t, int paramIndex);
-
- /**
- * Interpolate the tabel, t = ln(mu)
- */
- double interpolateLow(double t, int paramIndex);
-
-private:
-
- /**
- * The assignment operator is private and must never be called.
- * In fact, it should not even be implemented.
- */
- EWCouplings & operator=(const EWCouplings &) = delete;
-
-private:
-
- /**
- * Electoweak Scale
- */
- Energy ewScale_;
-
- /**
- * High Scale
- */
- Energy highScale_;
-
- /**
- * Low Scale
- */
- Energy lowScale_;
-
- /**
- * Whether or not to include SU3
- */
- bool includeSU3_;
-
- /**
- * Whether or not to include EW
- */
- bool includeEW_;
-
- /**
- * Whether or not the running couplings have been initialized
- */
- bool initialized_;
-
- /**
- * Masses of Standard Model particles
- */
- //@{
- /**
- * Mass Choice
- */
- bool massChoice_;
-
- /**
- * Z mass
- */
- Energy mZ_;
-
- /**
- * W mass
- */
- Energy mW_;
-
- /**
- * Top mass
- */
- Energy mT_;
-
- /**
- * Higgs boson mass
- */
- Energy mH_;
- //@}
-
- /**
- * Number of loops
- */
- unsigned int loops_;
-
- /**
- * Number of steps for Runga-Kutta (High scale)
- */
- unsigned int highSteps_;
-
- /**
- * Number of steps for Runga-Kutta (Low scale)
- */
- unsigned int lowSteps_;
-
- /**
- * Matrix to store the parameters
- */
- boost::numeric::ublas::matrix<double> table_;
-
- /**
- * Matrix to store the low energy parameters.
- * This will hold only aEM and a3 at mu<ewScale
- */
- boost::numeric::ublas::matrix<double> lowTable_;
-
- /**
- * Input values of the couplings
- */
- //@{
- /**
- * \f%\alpha_1(M_Z)\f$
- */
- double a1MZ_;
-
- /**
- * \f%\alpha_2(M_Z)\f$
- */
- double a2MZ_;
-
- /**
- * \f%\alpha_S(M_Z)\f$
- */
- double aSMZ_;
-
- /**
- * \f$\lambda_t\f$
- */
- double lambdat_;
- //@}
-
-};
-
-}
-
-#endif /* Herwig_EWCouplings_H */
diff --git a/MatrixElement/EW/EWProcess.h b/MatrixElement/EW/EWProcess.h
deleted file mode 100644
--- a/MatrixElement/EW/EWProcess.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// -*- C++ -*-
-//
-// EWProcess.h is a part of Herwig - A multi-purpose Monte Carlo event generator
-//
-// 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_EWProcess_H
-#define HERWIG_EWProcess_H
-
-namespace Herwig {
-
-namespace EWProcess {
-
- /**
- * Enumerates the processes for which we have SCET Wilson Coefficients
- */
- enum Process { QQQQ,
- QQQQiden,
- QtQtQQ,
- QQUU,
- QtQtUU,
- QQtRtR,
- QQDD,
- QtQtDD,
- QQLL,
- QQEE,
- UUUU,
- UUUUiden,
- tRtRUU,
- UUDD,
- tRtRDD,
- UULL,
- UUEE,
- DDDD,
- DDDDiden,
- DDLL,
- DDEE,
- LLLL,
- LLLLiden,
- LLEE,
- EEEE,
- EEEEiden,
- QQWW,
- QQPhiPhi,
- QQWG,
- QQBG,
- QQGG,
- QtQtGG,
- LLWW,
- LLPhiPhi,
- UUBB,
- UUPhiPhi,
- UUBG,
- UUGG,
- tRtRGG,
- DDBB,
- DDPhiPhi,
- DDBG,
- DDGG,
- EEBB,
- EEPhiPhi,
- LAST};
-}
-}
-
-#endif // HERWIG_EWProcess_H
diff --git a/MatrixElement/EW/ElectroWeakMatching.cc b/MatrixElement/EW/ElectroWeakMatching.cc
deleted file mode 100644
--- a/MatrixElement/EW/ElectroWeakMatching.cc
+++ /dev/null
@@ -1,1015 +0,0 @@
-// -*- C++ -*-
-//
-// ElectroWeakMatching.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
-//
-// Herwig is licenced under version 2 of the GPL, see COPYING for details.
-// Please respect the MCnet academic guidelines, see GUIDELINES for details.
-//
-//
-//
-#include "ElectroWeakMatching.h"
-#include "ElectroWeakReweighter.h"
-#include "GroupInvariants.h"
-#include <boost/numeric/ublas/operation.hpp>
-#include <boost/numeric/ublas/vector.hpp>
-
-using namespace Herwig;
-using namespace ElectroWeakMatching;
-using namespace GroupInvariants;
-using namespace EWProcess;
-
-boost::numeric::ublas::matrix<Complex>
-ElectroWeakMatching::electroWeakMatching(Energy mu,
- Energy2 s, Energy2 t, Energy2 u,
- Herwig::EWProcess::Process process,
- bool oneLoop,unsigned int iswap) {
- static const Complex I(0,1.0);
- using Constants::pi;
- Complex T = getT(s,t);
- Complex U = getU(s,u);
- // Z-Couplings
- double g_Lu = ElectroWeakReweighter::coupling()->g_Lu(mu);
- double g_Ld = ElectroWeakReweighter::coupling()->g_Ld(mu);
- double g_Le = ElectroWeakReweighter::coupling()->g_Le(mu);
- double g_Lnu = ElectroWeakReweighter::coupling()->g_Lnu(mu);
- double g_Ru = ElectroWeakReweighter::coupling()->g_Ru(mu);
- double g_Rd = ElectroWeakReweighter::coupling()->g_Rd(mu);
- double g_Re = ElectroWeakReweighter::coupling()->g_Re(mu);
- double g_W = ElectroWeakReweighter::coupling()->g_W(mu);
- double g_phiPlus = ElectroWeakReweighter::coupling()->g_phiPlus(mu);
- // Weinberg Angle:
- double cos2 = ElectroWeakReweighter::coupling()->Cos2thW(mu);
- double sin2 = 1.0-cos2;
- double cos = sqrt(cos2);
- double sin = sqrt(sin2);
-
- boost::numeric::ublas::matrix<Complex> R0,G2,Dw,Dz;
-
- switch (process) {
- case QQQQ:
- case QQQQiden:
- case QtQtQQ:
- {
- unsigned int numGauge = 4, numBrokenGauge = 12;
- R0=boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2=boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw=boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz=boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,1) = R0(1,1) = R0(2,1) = R0(3,1) = 1.0;
- R0(0,0) = R0(3,0) = 0.25;
- R0(1,0) = R0(2,0) = -0.25;
- R0(4,0) = R0(5,0) = 0.5;
- R0(6,3) = R0(7,3) = R0(8,3) = R0(9,3) = 1.0;
- R0(6,2) = R0(9,2) = 0.25;
- R0(7,2) = R0(8,2) = -0.25;
- R0(10,2) = R0(11,2) = 0.5;
- if (oneLoop) {
- double g11 = g_Lu;
- double g12 = g_Ld;
- double g21 = g_Lu;
- double g22 = g_Ld;
- Complex w0(0.),w1(0.),w2(0.);
- Complex z1(0.),z2(0.),z3(0.),z4(0.),z5(0.);
- boost::numeric::ublas::matrix<Complex> gam2;
- if(iswap==0) {
- w0 = 0.5*I*pi;
- w1 = -0.5*(T-U);
- w2 = -0.5*(T+U);
- z1 = 2.0*g11*g21*(T-U) - I*pi*(g11*g11+g21*g21);
- z2 = 2.0*g21*g12*(T-U) - I*pi*(g21*g21+g12*g12);
- z3 = 2.0*g22*g11*(T-U) - I*pi*(g22*g22+g11*g11);
- z4 = 2.0*g12*g22*(T-U) - I*pi*(g12*g12+g22*g22);
- z5 = (g11*g21+g12*g22)*T - (g21*g12+g11*g22)*U
- - 0.5*I*pi*(g11*g11+g12*g12+g21*g21+g22*g22);
- gam2 = Gamma2(U,T);
- }
- else if(iswap==1) {
- w0 = -0.5*(T-I*pi);
- w1 = 0.5*U;
- w2 = -0.5*(U-2.*T);
- z1 = 2.0*g11*g21*(-U) + ( T- I*pi)*(g11*g11+g21*g21);
- z2 = 2.0*g21*g12*(-U) + ( T- I*pi)*(g21*g21+g12*g12);
- z3 = 2.0*g22*g11*(-U) + ( T- I*pi)*(g22*g22+g11*g11);
- z4 = 2.0*g12*g22*(-U) + ( T- I*pi)*(g12*g12+g22*g22);
- z5 = -(g11*g21+g12*g22)*T - (g21*g12+g11*g22)*(U-T)
- + 0.5*(T-I*pi)*(g11*g11+g12*g12+g21*g21+g22*g22);
- gam2 = Gamma2ST(U,T);
- }
- else if(iswap==2) {
- w0 = -0.5*(U-I*pi);
- w1 = -0.5*T;
- w2 = -0.5*(T-2.*U);
- z1 = 2.0*g11*g21*T +(U-I*pi)*(g11*g11+g21*g21);
- z2 = 2.0*g21*g12*T +(U-I*pi)*(g21*g21+g12*g12);
- z3 = 2.0*g22*g11*T +(U-I*pi)*(g22*g22+g11*g11);
- z4 = 2.0*g12*g22*T +(U-I*pi)*(g12*g12+g22*g22);
- z5 = (g11*g21+g12*g22)*(T-U) + (g21*g12+g11*g22)*U
- + 0.5*(U-I*pi)*(g11*g11+g12*g12+g21*g21+g22*g22);
- gam2 = Gamma2SU(U,T);
- }
- else
- assert(false);
- // Dw
- for(unsigned int ix=0;ix<numBrokenGauge;++ix) {
- Dw(ix,ix) = w0;
- }
- for(unsigned int ix=0;ix<numBrokenGauge;ix+=6) {
- Dw(ix+0,ix+0) += w1;
- Dw(ix+3,ix+3) += w1;
- Dw(ix+1,ix+1) +=-w1;
- Dw(ix+2,ix+2) +=-w1;
- Dw(ix+4,ix+4) += w2;
- Dw(ix+5,ix+5) += w2;
- }
- // DZ
- for(unsigned int ix=0;ix<numBrokenGauge;ix+=6) {
- Dz(ix+0,ix+0) = z1;
- Dz(ix+1,ix+1) = z2;
- Dz(ix+2,ix+2) = z3;
- Dz(ix+3,ix+3) = z4;
- Dz(ix+4,ix+4) = z5;
- Dz(ix+5,ix+5) = z5;
- }
- // G2
- G2(0,0) += gam2(0,0);
- G2(0,1) += gam2(0,1);
- G2(1,0) += gam2(1,0);
- G2(1,1) += gam2(1,1);
- G2(2,2) += gam2(0,0);
- G2(2,3) += gam2(0,1);
- G2(3,2) += gam2(1,0);
- G2(3,3) += gam2(1,1);
- }
- }
- break;
- case QQUU:
- case QtQtUU:
- case QQtRtR:
- {
- unsigned int numGauge = 2, numBrokenGauge = 4;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = R0(1,0) = R0(2,1) = R0(3,1) = 1.0;
- if (oneLoop) {
- double g11 = g_Lu;
- double g12 = g_Ld;
- //double g21 = g_Ru;
- double g22 = g_Ru;
- Complex w1(0.),z1(0.),z2(0.);
- if(iswap==0) {
- w1 = 0.25*I*pi;
- z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- z2 = 2.0*g12*g22*(T-U) - I*pi*(g12*g12+g22*g22);
- G2 = Gamma2Singlet();
- }
- else if(iswap==1) {
- w1 = -0.25*(T-I*pi);
- z1 = -2.0*g11*g22*U +(T-I*pi)*(g11*g11+g22*g22);
- z2 = -2.0*g12*g22*U +(T-I*pi)*(g12*g12+g22*g22);
- G2 = Gamma2SingletST(T);
- }
- else if(iswap==2) {
- w1 = -0.25*(U-I*pi);
- z1 = 2.0*g11*g22*T +(U-I*pi)*(g11*g11+g22*g22);
- z2 = 2.0*g12*g22*T +(U-I*pi)*(g12*g12+g22*g22);
- G2 = Gamma2SingletSU(U);
- }
- else
- assert(false);
- for(unsigned int ix=0;ix<numBrokenGauge;++ix) Dw(ix,ix) = w1;
-
- for(unsigned int ix=0;ix<numBrokenGauge;ix+=2) {
- Dz(ix+0,ix+0) = z1;
- Dz(ix+1,ix+1) = z2;
- }
- }
- }
- break;
- case QQDD:
- case QtQtDD:
- {
- unsigned int numGauge = 2, numBrokenGauge = 4;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = R0(1,0) = R0(2,1) = R0(3,1) = 1.0;
- if (oneLoop) {
- double g11 = g_Lu;
- double g12 = g_Ld;
- //double g21 = g_Rd;
- double g22 = g_Rd;
- Complex w1(0.),z1(0.),z2(0.);
- if(iswap==0) {
- w1 = 0.25*I*pi;
- z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- z2 = 2.0*g12*g22*(T-U) - I*pi*(g12*g12+g22*g22);
- G2 = Gamma2Singlet();
- }
- else if(iswap==1) {
- w1 =-0.25*(T-I*pi);
- z1 =-2.0*g11*g22*U + (T-I*pi)*(g11*g11+g22*g22);
- z2 =-2.0*g12*g22*U + (T-I*pi)*(g12*g12+g22*g22);
- G2 = Gamma2SingletST(T);
- }
- else if(iswap==2) {
- w1 =-0.25*(U-I*pi);
- z1 = 2.0*g11*g22*T + (U-I*pi)*(g11*g11+g22*g22);
- z2 = 2.0*g12*g22*T + (U-I*pi)*(g12*g12+g22*g22);
- G2 = Gamma2Singlet();
- }
- else
- assert(false);
- for(unsigned int ix=0;ix<numBrokenGauge;++ix) Dw(ix,ix) = w1;
- for(unsigned int ix=0;ix<numBrokenGauge;ix+=2) {
- Dz(ix+0,ix+0) = z1;
- Dz(ix+1,ix+1) = z2;
- }
- }
- }
- break;
- case QQLL:
- {
- assert(iswap==0);
- unsigned int numGauge = 2, numBrokenGauge = 6;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,1) = R0(1,1) = R0(2,1) = R0(3,1) = 1.0;
- R0(0,0) = R0(3,0) = 0.25;
- R0(1,0) = R0(2,0) = -0.25;
- R0(4,0) = R0(5,0) = 0.5;
- if (oneLoop) {
- double g11 = g_Lu;
- double g12 = g_Ld;
- double g21 = g_Lnu;
- double g22 = g_Le;
-
- for (unsigned int i=0; i<6; ++i) {
- Dw(i,i) = 0.5*I*pi;
- }
- Complex w1 = (-1.0/2.0)*(T-U);
- Complex w2 = (-1.0/2.0)*(T+U);
- Dw(0,0) += w1;
- Dw(3,3) += w1;
- Dw(1,1) += -1.0*w1;
- Dw(2,2) += -1.0*w1;
- Dw(4,4) += w2;
- Dw(5,5) += w2;
-
- Complex z1 = 2.0*g11*g21*(T-U) - I*pi*(g11*g11+g21*g21);
- Complex z2 = 2.0*g21*g12*(T-U) - I*pi*(g21*g21+g12*g12);
- Complex z3 = 2.0*g22*g11*(T-U) - I*pi*(g22*g22+g11*g11);
- Complex z4 = 2.0*g12*g22*(T-U) - I*pi*(g12*g12+g22*g22);
- Complex z5 = (g11*g21+g12*g22)*T - (g21*g12+g11*g22)*U
- - 0.5*I*pi*(g11*g11+g12*g12+g21*g21+g22*g22);
- Dz(0,0) = z1;
- Dz(1,1) = z2;
- Dz(2,2) = z3;
- Dz(3,3) = z4;
- Dz(4,4) = Dz(5,5) = z5;
-
- G2 = Gamma2(U,T);
- }
- }
- break;
- case QQEE:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 2;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = R0(1,0) = 1.0;
- if (oneLoop) {
- double g11 = g_Lu;
- double g12 = g_Ld;
- //double g21 = g_Re;
- double g22 = g_Re;
-
- Complex w1 = 0.25*I*pi;
- Dw(0,0) = Dw(1,1) = w1;
-
- Complex z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- Complex z2 = 2.0*g12*g22*(T-U) - I*pi*(g12*g12+g22*g22);
- Dz(0,0) = z1;
- Dz(1,1) = z2;
-
- G2(0,0) = Gamma2Singlet()(0,0);
- }
- }
- break;
- case UUUU:
- case UUUUiden:
- case tRtRUU:
- {
- unsigned int numGauge = 2, numBrokenGauge = 2;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = R0(1,1) = 1.0;
- if (oneLoop) {
- double g11 = g_Ru;
- //double g12 = g_Ru;
- //double g21 = g_Ru;
- double g22 = g_Ru;
- // There is no Dw contribution for two SU(2) singlets.
- Complex z1(0.);
- if(iswap==0) {
- z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- }
- else if(iswap==1) {
- z1 =-2.0*g11*g22*U + (T-I*pi)*(g11*g11+g22*g22);
- }
- else if(iswap==2) {
- z1 = 2.0*g11*g22*T + (U-I*pi)*(g11*g11+g22*g22);
- }
- Dz(0,0) = Dz(1,1) = z1;
- }
- }
- break;
- case UUDD:
- case tRtRDD:
- {
- unsigned int numGauge = 2, numBrokenGauge = 2;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = R0(1,1) = 1.0;
- if (oneLoop) {
- double g11 = g_Ru;
- //double g12 = g_Ru;
- //double g21 = g_Rd;
- double g22 = g_Rd;
- // There is no Dw contribution for two SU(2) singlets.
- Complex z1(0.);
- if(iswap==0) {
- z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- }
- else if(iswap==1) {
- z1 =-2.0*g11*g22*U + (T-I*pi)*(g11*g11+g22*g22);
- }
- else if(iswap==2) {
- z1 = 2.0*g11*g22*T + (U-I*pi)*(g11*g11+g22*g22);
- }
- else
- assert(false);
- Dz(0,0) = Dz(1,1) = z1;
- }
- }
- break;
- case UULL:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 2;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = R0(1,0) = 1.0;
- if (oneLoop) {
- double g11 = g_Lnu;
- double g12 = g_Le;
- //double g21 = g_Ru;
- double g22 = g_Ru;
-
- Complex w1 = 0.25*I*pi;
- Dw(0,0) = Dw(1,1) = w1;
-
- Complex z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- Complex z2 = 2.0*g12*g22*(T-U) - I*pi*(g12*g12+g22*g22);
- Dz(0,0) = z1;
- Dz(1,1) = z2;
-
- G2(0,0) = Gamma2Singlet()(0,0);
- }
- }
- break;
- case UUEE:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 1;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = 1.0;
- if (oneLoop) {
- double g11 = g_Ru;
- //double g12 = g_Ru;
- //double g21 = g_Re;
- double g22 = g_Re;
- // There is no Dw contribution for two SU(2) singlets.
- Complex z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- Dz(0,0) = z1;
- }
- }
- break;
- case DDDD:
- case DDDDiden:
- {
- unsigned int numGauge = 2, numBrokenGauge = 2;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = R0(1,1) = 1.0;
- if (oneLoop) {
- double g11 = g_Rd;
- //double g12 = g_Rd;
- //double g21 = g_Rd;
- double g22 = g_Rd;
- // There is no Dw contribution for two SU(2) singlets.
- Complex z1(0.);
- if(iswap==0) {
- z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- }
- else if(iswap==1) {
- z1 =-2.0*g11*g22*U +(T-I*pi)*(g11*g11+g22*g22);
- }
- else if(iswap==2) {
- z1 = 2.0*g11*g22*T +(U-I*pi)*(g11*g11+g22*g22);
- }
- else
- assert(false);
- Dz(0,0) = Dz(1,1) = z1;
- }
- }
- break;
- case DDLL:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 2;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = R0(1,0) = 1.0;
- if (oneLoop) {
- double g11 = g_Lnu;
- double g12 = g_Le;
- //double g21 = g_Rd;
- double g22 = g_Rd;
-
- Complex w1 = 0.25*I*pi;
- Dw(0,0) = Dw(1,1) = w1;
-
- Complex z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- Complex z2 = 2.0*g12*g22*(T-U) - I*pi*(g12*g12+g22*g22);
- Dz(0,0) = z1;
- Dz(1,1) = z2;
-
- G2(0,0) = Gamma2Singlet()(0,0);
- }
- }
- break;
- case DDEE:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 1;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0 *= 0.0; Dw = Dz *= 0.0;
- R0(0,0) = 1.0;
- if (oneLoop) {
- double g11 = g_Rd;
- //double g12 = g_Rd;
- //double g21 = g_Re;
- double g22 = g_Re;
- // There is no Dw contribution for two SU(2) singlets.
- Complex z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- Dz(0,0) = z1;
- }
- }
- break;
- case LLLL:
- case LLLLiden:
- {
- assert(iswap==0);
- unsigned int numGauge = 2, numBrokenGauge = 6;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,1) = R0(1,1) = R0(2,1) = R0(3,1) = 1.0;
- R0(0,0) = R0(3,0) = 0.25;
- R0(1,0) = R0(2,0) = -0.25;
- R0(4,0) = R0(5,0) = 0.5;
- if (oneLoop) {
- double g11 = g_Lnu;
- double g12 = g_Le;
- double g21 = g_Lnu;
- double g22 = g_Le;
-
- for (int i=0; i<6; i++) {
- Dw(i,i) = 0.5*I*pi;
- }
- Complex w1 = (-1.0/2.0)*(T-U);
- Complex w2 = (-1.0/2.0)*(T+U);
- Dw(0,0) += w1;
- Dw(3,3) += w1;
- Dw(1,1) += -1.0*w1;
- Dw(2,2) += -1.0*w1;
- Dw(4,4) += w2;
- Dw(5,5) += w2;
-
- Complex z1 = 2.0*g11*g21*(T-U) - I*pi*(g11*g11+g21*g21);
- Complex z2 = 2.0*g21*g12*(T-U) - I*pi*(g21*g21+g12*g12);
- Complex z3 = 2.0*g22*g11*(T-U) - I*pi*(g22*g22+g11*g11);
- Complex z4 = 2.0*g12*g22*(T-U) - I*pi*(g12*g12+g22*g22);
- Complex z5 = (g11*g21+g12*g22)*T - (g21*g12+g11*g22)*U
- - 0.5*I*pi*(g11*g11+g12*g12+g21*g21+g22*g22);
- Dz(0,0) = z1;
- Dz(1,1) = z2;
- Dz(2,2) = z3;
- Dz(3,3) = z4;
- Dz(4,4) = Dz(5,5) = z5;
-
- G2 = Gamma2(U,T);
- }
- }
- break;
- case LLEE:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 2;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = R0(1,0) = 1.0;
- if (oneLoop) {
- double g11 = g_Lnu;
- double g12 = g_Le;
- //double g21 = g_Re;
- double g22 = g_Re;
-
- Complex w1 = 0.25*I*pi;
- Dw(0,0) = Dw(1,1) = w1;
-
- Complex z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- Complex z2 = 2.0*g12*g22*(T-U) - I*pi*(g12*g12+g22*g22);
- Dz(0,0) = z1;
- Dz(1,1) = z2;
-
- G2(0,0) = Gamma2Singlet()(0,0);
- }
- }
- break;
- case EEEE:
- case EEEEiden:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 1;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = 1.0;
- if (oneLoop) {
- double g11 = g_Re;
- //double g12 = g_Re;
- //double g21 = g_Re;
- double g22 = g_Re;
- // There is no Dw contribution for two SU(2) singlets.
- Complex z1 = 2.0*g11*g22*(T-U) - I*pi*(g11*g11+g22*g22);
- Dz(0,0) = z1;
- }
- }
- break;
- case QQWW:
- case LLWW:
- {
- assert(iswap==0);
- unsigned int numGauge = 5, numBrokenGauge = 20;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = 1.0; R0(0,1) = 0.5;
- R0(1,0) = 1.0; R0(1,1) = -0.5;
- R0(2,0) = cos2; R0(2,2) = -0.5*sin*cos; R0(2,3) = -0.5*sin*cos; R0(2,4) = sin2;
- R0(3,0) = sin*cos; R0(3,2) = 0.5*cos2; R0(3,3) = -0.5*sin2; R0(3,4) = -sin*cos;
- R0(4,0) = sin*cos; R0(4,2) = -0.5*sin2; R0(4,3) = 0.5*cos2; R0(4,4) = -sin*cos;
- R0(5,0) = sin2; R0(5,2) = 0.5*sin*cos; R0(5,3) = 0.5*sin*cos; R0(5,4) = cos2;
- R0(6,0) = 1.0; R0(6,1) = -0.5;
- R0(7,0) = 1.0; R0(7,1) = 0.5;
- R0(8,0) = cos2; R0(8,2) = 0.5*sin*cos; R0(8,3) = 0.5*sin*cos; R0(8,4) = sin2;
- R0(9,0) = sin*cos; R0(9,2) = -0.5*cos2; R0(9,3) = 0.5*sin2; R0(9,4) = -sin*cos;
- R0(10,0) = sin*cos; R0(10,2) = 0.5*sin2; R0(10,3) = -0.5*cos2; R0(10,4) = -sin*cos;
- R0(11,0) = sin2; R0(11,2) = -0.5*sin*cos; R0(11,3) = -0.5*sin*cos; R0(11,4) = cos2;
- R0(12,1) = -cos/sqrt(2.0); R0(12,3) = -sin/sqrt(2.0);
- R0(13,1) = -sin/sqrt(2.0); R0(13,3) = cos/sqrt(2.0);
- R0(14,1) = cos/sqrt(2.0); R0(14,2) = -sin/sqrt(2.0);
- R0(15,1) = sin/sqrt(2.0); R0(15,2) = cos/sqrt(2.0);
- R0(16,1) = -cos/sqrt(2.0); R0(16,2) = -sin/sqrt(2.0);
- R0(17,1) = -sin/sqrt(2.0); R0(17,2) = cos/sqrt(2.0);
- R0(18,1) = cos/sqrt(2.0); R0(18,3) = -sin/sqrt(2.0);
- R0(19,1) = sin/sqrt(2.0); R0(19,3) = cos/sqrt(2.0);
- if (oneLoop) {
- double gW = g_W;
- double g1(0.),g2(0.);
- if (process==QQWW) {
- g1 = g_Lu;
- g2 = g_Ld;
- }
- else if (process==LLWW) {
- g1 = g_Lnu;
- g2 = g_Le;
- }
-
- Complex w1 = T-U+5.0/4.0*I*pi;
- Complex w2 = -T+U+5.0/4.0*I*pi;
- Complex w3 = -0.5*(T+U) + 3.0/4.0*I*pi;
- Complex w4 = 0.25*I*pi;
- Dw(0,0) = Dw(7,7) = w1;
- Dw(1,1) = Dw(6,6) = w2;
- for (unsigned int i=12; i<20; i++) {
- Dw(i,i) = w3;
- }
- Dw(2,2) = Dw(3,3) = Dw(4,4) = Dw(5,5) = w4;
- Dw(8,8) = Dw(9,9) = Dw(10,10) = Dw(11,11) = w4;
-
- Complex z1 = 2.0*g1*gW*(U-T) - I*pi*(g1*g1+gW*gW);
- Complex z2 = 2.0*g1*gW*(T-U) - I*pi*(g1*g1+gW*gW);
- Complex z3 = 2.0*g2*gW*(U-T) - I*pi*(g2*g2+gW*gW);
- Complex z4 = 2.0*g2*gW*(T-U) - I*pi*(g2*g2+gW*gW);
- Complex z5 = -(g2*gW)*T + (g1*gW)*U - I*pi*(g1*g2+g1*gW-g2*gW);
- Complex z6 = (g1*gW)*T - (g2*gW)*U - I*pi*(g1*g2+g1*gW-g2*gW);
- Complex z7 = -I*pi*g1*g1;
- Complex z8 = -I*pi*g2*g2;
- Dz(0,0) = z1;
- Dz(1,1) = z2;
- Dz(2,2) = Dz(3,3) = Dz(4,4) = Dz(5,5) = z7;
- Dz(6,6) = z3;
- Dz(7,7) = z4;
- Dz(8,8) = Dz(9,9) = Dz(10,10) = Dz(11,11) = z8;
- Dz(12,12) = Dz(13,13) = Dz(16,16) = Dz(17,17) = z5;
- Dz(14,14) = Dz(15,15) = Dz(18,18) = Dz(19,19) = z6;
-
- G2 = Gamma2w(U,T);
- }
- }
- break;
- case QQPhiPhi:
- case LLPhiPhi:
- {
- assert(iswap==0);
- unsigned int numGauge = 2, numBrokenGauge = 14;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = 0.25; R0(0,1) = 1.0;
- R0(1,0) = -1.0/8.0; R0(1,1) = 0.5;
- R0(2,0) = I/8.0; R0(2,1) = -I/2.0;
- R0(3,0) = -I/8.0; R0(3,1) = I/2.0;
- R0(4,0) = -1.0/8.0; R0(4,1) = 1.0/2.0;
- R0(5,0) = -1.0/4.0; R0(5,1) = 1.0;
- R0(6,0) = 1.0/8.0; R0(6,1) = 1.0/2.0;
- R0(7,0) = -I/8.0; R0(7,1) = -I/2.0;
- R0(8,0) = I/8.0; R0(8,1) = I/2.0;
- R0(9,0) = 1.0/8.0; R0(9,1) = 1.0/2.0;
- R0(10,0) = -1.0/(2.0*sqrt(2.0));
- R0(11,0) = I/(2.0*sqrt(2.0));
- R0(12,0) = -1.0/(2.0*sqrt(2.0));
- R0(13,0) = -I/(2.0*sqrt(2.0));
-
- if (oneLoop) {
- double g1(0.),g2(0.);
- if (process==QQPhiPhi) {
- g1 = g_Lu;
- g2 = g_Ld;
- }
- else if (process==LLPhiPhi) {
- g1 = g_Lnu;
- g2 = g_Le;
- }
- else
- assert(false);
- double g3 = g_phiPlus;
-
- Complex w0 = 0.25*I*pi;
- Complex w1 = 0.5*(T-U) + 0.5*I*pi;
- Complex w2 = -0.5*(T-U) + 0.5*I*pi;
- Complex w3 = 0.25*I*(T-U);
- Complex w4 = -0.25*(T+U) + 0.25*I*pi;
- Dw(0,0) = w2;
- Dw(1,1) = w0; Dw(1,2) = w3; Dw(1,3) = -w3; Dw(1,4) = w0;
- Dw(2,1) = -w3; Dw(2,2) = w0; Dw(2,3) = -w0; Dw(2,4) = -w3;
- Dw(3,1) = w3; Dw(3,2) = -w0; Dw(3,3) = w0; Dw(3,4) = w3;
- Dw(4,1) = w0; Dw(4,2) = w3; Dw(4,3) = -w3; Dw(4,4) = w0;
- Dw(5,5) = w1;
- Dw(6,6) = w0; Dw(6,7) = -w3; Dw(6,8) = w3; Dw(6,9) = w0;
- Dw(7,6) = w3; Dw(7,7) = w0; Dw(7,8) = -w0; Dw(7,9) = w3;
- Dw(8,6) = -w3; Dw(8,7) = -w0; Dw(8,8) = w0; Dw(8,9) = -w3;
- Dw(9,6) = w0; Dw(9,7) = -w3; Dw(9,8) = w3; Dw(9,9) = w0;
- Dw(10,10) = w4; Dw(10,11) = I*w4;
- Dw(11,10) = -I*w4; Dw(11,11) = w4;
- Dw(12,12) = w4; Dw(12,13) = -I*w4;
- Dw(13,12) = I*w4; Dw(13,13) = w4;
-
- Complex z1 = 2.0*g3*g1*(T-U) - I*pi*(g3*g3+g1*g1);
- Complex z2 = 2.0*g3*g2*(T-U) - I*pi*(g3*g3+g2*g2);
- Complex z3 = -I*pi*g1*g1;
- Complex z4 = 0.5*I*g1*(T-U);
- Complex z5 = 0.25*I*pi;
- Complex z6 = -I*pi*g2*g2;
- Complex z7 = 0.5*I*g2*(T-U);
- Complex z8 = g3*g1*T-g3*g2*U-I*pi*(g1*g2-g2*g3+g1*g3);
- Complex z9 = 0.5*I*g2*T-0.5*I*g1*U+pi/2.0*g2-pi/2.0*g1+pi/2.0*g3;
- Dz(0,0) = z1;
- Dz(1,1) = z3; Dz(1,2) = -z4; Dz(1,3) = z4; Dz(1,4) = -z5;
- Dz(2,1) = z4; Dz(2,2) = z3; Dz(2,3) = z5; Dz(2,4) = z4;
- Dz(3,1) = -z4; Dz(3,2) = z5; Dz(3,3) = z3; Dz(3,4) = -z4;
- Dz(4,1) = -z5; Dz(4,2) = -z4; Dz(4,3) = z4; Dz(4,4) = z3;
- Dz(5,5) = z2;
- Dz(6,6) = z6; Dz(6,7) = -z7; Dz(6,8) = z7; Dz(6,9) = -z5;
- Dz(7,6) = z7; Dz(7,7) = z6; Dz(7,8) = z5; Dz(7,9) = z7;
- Dz(8,6) = -z7; Dz(8,7) = z5; Dz(8,8) = z6; Dz(8,9) = -z7;
- Dz(9,6) = -z5; Dz(9,7) = -z7; Dz(9,8) = z7; Dz(9,9) = z6;
- Dz(10,10) = z8; Dz(10,11) = -z9;
- Dz(11,10) = z9; Dz(11,11) = z8;
- Dz(12,12) = z8; Dz(12,13) = z9;
- Dz(13,12) = -z9; Dz(13,13) = z8;
-
- G2 = Gamma2(U,T);
- }
- }
- break;
- case QQWG:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 6;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = 1.0/sqrt(2);
- R0(1,0) = 1.0/sqrt(2);
- R0(2,0) = cos/2.0;
- R0(3,0) = sin/2.0;
- R0(4,0) = -cos/2.0;
- R0(5,0) = -sin/2.0;
- if (oneLoop) {
- double g1 = g_Lu;
- double g2 = g_Ld;
- double gW = g_W;
-
- Complex w1 = -0.5*(T+U) + 0.75*I*pi;
- Complex w2 = 0.25*I*pi;
- Dw(0,0) = Dw(1,1) = w1;
- Dw(2,2) = Dw(3,3) = Dw(4,4) = Dw(5,5) = w2;
-
- Complex z1 = gW*g1*T - gW*g2*U - I*pi*(g1*g2+g1*gW-g2*gW);
- Complex z2 = gW*g1*U - gW*g2*T - I*pi*(g2*g1+g1*gW-g2*gW);
- Complex z3 = -I*pi*g1*g1;
- Complex z4 = -I*pi*g2*g2;
- Dz(0,0) = z1;
- Dz(1,1) = z2;
- Dz(2,2) = z3;
- Dz(3,3) = z3;
- Dz(4,4) = z4;
- Dz(5,5) = z4;
-
- G2(0,0) = -7.0/4.0*I*pi + (U+T);
- }
- }
- break;
- case QQBG:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 4;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = -sin;
- R0(1,0) = cos;
- R0(2,0) = -sin;
- R0(3,0) = cos;
- if (oneLoop) {
- double g1 = g_Lu;
- double g2 = g_Ld;
- Complex w2 = 0.25*I*pi;
- Dw(0,0) = Dw(1,1) = Dw(2,2) = Dw(3,3) = w2;
- Complex z3 = -I*pi*g1*g1;
- Complex z4 = -I*pi*g2*g2;
- Dz(0,0) = z3;
- Dz(1,1) = z3;
- Dz(2,2) = z4;
- Dz(3,3) = z4;
- G2(0,0) = Gamma2Singlet()(0,0);
- }
- }
- break;
- case QQGG:
- case QtQtGG:
- {
- unsigned int numGauge = 3, numBrokenGauge = 6;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = R0(3,0) = 1.0;
- R0(1,1) = R0(4,1) = 1.0;
- R0(2,2) = R0(5,2) = 1.0;
- double g1 = g_Lu;
- double g2 = g_Ld;
- Complex w2(0.),z3(0.),z4(0.);
- if (oneLoop) {
- if(iswap==0) {
- w2 = 0.25*I*pi;
- z3 = -I*pi*g1*g1;
- z4 = -I*pi*g2*g2;
- G2(0,0) = G2(1,1) = G2(2,2) = Gamma2Singlet()(0,0);
- }
- else if(iswap==1) {
- w2 = 0.25*(-T+I*pi);
- z3 = (T-I*pi)*sqr(g1);
- z4 = (T-I*pi)*sqr(g2);
- G2(0,0) = G2(1,1) = G2(2,2) = Gamma2SingletST(T)(0,0);
- }
- else if(iswap==2) {
- w2 = 0.25*(-U+I*pi);
- z3 = (U-I*pi)*g1*g1;
- z4 = (U-I*pi)*g2*g2;
- G2(0,0) = G2(1,1) = G2(2,2) = Gamma2SingletSU(U)(0,0);
- }
- else
- assert(false);
- Dw(0,0) = Dw(1,1) = Dw(2,2) = Dw(3,3) = Dw(4,4) = Dw(5,5) = w2;
- Dz(0,0) = Dz(1,1) = Dz(2,2) = z3;
- Dz(3,3) = Dz(4,4) = Dz(5,5) = z4;
- }
- }
- break;
- case UUBB:
- case DDBB:
- case EEBB:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 4;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = sin2;
- R0(1,0) = -sin*cos;
- R0(2,0) = -sin*cos;
- R0(3,0) = cos2;
- if (oneLoop) {
- double g1(0.);
- if (process==UUBB) {
- g1 = g_Ru;
- }
- else if (process==DDBB) {
- g1 = g_Rd;
- }
- else if (process==EEBB) {
- g1 = g_Re;
- }
- else
- assert(false);
- // There is no Dw contribution for two SU(2) singlets.
- Complex z1 = -I*pi*g1*g1;
- Dz(0,0) = Dz(1,1) = Dz(2,2) = Dz(3,3) = z1;
- }
- }
- break;
- case UUPhiPhi:
- case DDPhiPhi:
- case EEPhiPhi:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 5;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = 1.0;
- R0(1,0) = 0.5;
- R0(2,0) = -0.5*I;
- R0(3,0) = 0.5*I;
- R0(4,0) = 0.5;
- if (oneLoop) {
- double g1(0.);
- if (process==UUPhiPhi) {
- g1 = g_Ru;
- }
- else if (process==DDPhiPhi) {
- g1 = g_Rd;
- }
- else if (process==EEPhiPhi) {
- g1 = g_Re;
- }
- double g3 = g_phiPlus;
- Dw(0,0) = Dw(1,4) = Dw(4,1) = 0.25*I*pi;
- Dw(2,3) = Dw(3,2) = -0.25*I*pi;
- Complex z1 = 2.0*g3*g1*(T-U) - I*pi*(g3*g3+g1*g1);
- Complex z2 = 0.5*I*g1*g1;
- Complex z3 = -I*pi*g1*g1;
- Complex z4 = 0.25*I*pi;
- Dz(0,0) = z1;
- Dz(1,1) = z3; Dz(1,2) = -z2; Dz(1,3) = z2; Dz(1,4) = -z4;
- Dz(2,1) = z2; Dz(2,2) = z3; Dz(2,3) = z4; Dz(2,4) = z2;
- Dz(3,1) = -z2; Dz(3,2) = z4; Dz(3,3) = z3; Dz(3,4) = -z2;
- Dz(4,1) = -z4; Dz(4,2) = -z2; Dz(4,3) = z2; Dz(4,4) = z3;
- G2(0,0) = Gamma2Singlet()(0,0);
- }
- }
- break;
- case UUBG:
- case DDBG:
- {
- assert(iswap==0);
- unsigned int numGauge = 1, numBrokenGauge = 2;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = -sin;
- R0(1,0) = cos;
- if (oneLoop) {
- double g1(0.);
- if (process==UUBG) {
- g1 = g_Ru;
- }
- else if (process==DDBG) {
- g1 = g_Rd;
- }
- else
- assert(false);
- // There is no Dw contribution for two SU(2) singlets.
- Complex z1 = -I*pi*g1*g1;
- Dz(0,0) = Dz(1,1) = z1;
- }
- }
- break;
- case UUGG:
- case tRtRGG:
- case DDGG:
- {
- unsigned int numGauge = 3, numBrokenGauge = 3;
- R0 = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numGauge);
- G2 = boost::numeric::ublas::zero_matrix<Complex>(numGauge,numGauge);
- Dw = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Dz = boost::numeric::ublas::zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- R0(0,0) = R0(1,1) = R0(2,2) = 1.0;
- if (oneLoop) {
- double g1(0.);
- if ((process==UUGG)||(process==tRtRGG)) {
- g1 = g_Ru;
- }
- else if (process==DDGG) {
- g1 = g_Rd;
- }
- else
- assert(false);
- Complex z1(0.);
- // There is no Dw contribution for two SU(2) singlets.
- if(iswap==0) {
- z1 = -I*pi*sqr(g1);
- }
- else if(iswap==1) {
- z1 = (T-I*pi)*sqr(g1);
- }
- else if(iswap==2) {
- z1 = (U-I*pi)*sqr(g1);
- }
- else
- assert(false);
- Dz(0,0) = Dz(1,1) = Dz(2,2) = z1;
- }
- }
- break;
- default:
- assert(false);
- }
-
- double aW = ElectroWeakReweighter::coupling()->aW(mu);
- double aZ = ElectroWeakReweighter::coupling()->aZ(mu);
- Energy mZ = ElectroWeakReweighter::coupling()->mZ();
- Energy mW = ElectroWeakReweighter::coupling()->mW();
-
- if (!oneLoop) {
- return R0;
- }
- boost::numeric::ublas::matrix<Complex> output(R0);
- boost::numeric::ublas::matrix<Complex> temp(R0.size1(),R0.size2());
- boost::numeric::ublas::axpy_prod(R0,G2,temp);
- output+=aW/(4.0*pi)*4.0*log(mW/mu)*temp;
- boost::numeric::ublas::axpy_prod(Dw,R0,temp);
- output+=aW/(4.0*pi)*4.0*log(mW/mu)*temp;
- boost::numeric::ublas::axpy_prod(Dz,R0,temp);
- output+=aZ/(4.0*pi)*4.0*log(mZ/mu)*temp;
- return output;
-}
diff --git a/MatrixElement/EW/ElectroWeakMatching.h b/MatrixElement/EW/ElectroWeakMatching.h
deleted file mode 100644
--- a/MatrixElement/EW/ElectroWeakMatching.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// -*- C++ -*-
-//
-// ElectroWeakMatching.h is a part of Herwig - A multi-purpose Monte Carlo event generator
-//
-// 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_ElectroWeakMatching_H
-#define HERWIG_ElectroWeakMatching_H
-#include "ThePEG/Config/ThePEG.h"
-#include "ThePEG/Config/Unitsystem.h"
-#include "EWProcess.h"
-// work around a Boost 1.64 bug where ublas headers would fail otherwise
-#include <boost/version.hpp>
-#if (BOOST_VERSION / 100 >= 1064)
-#include <boost/serialization/array_wrapper.hpp>
-#endif
-#include <boost/numeric/ublas/matrix.hpp>
-
-namespace Herwig {
-using namespace ThePEG;
-
-namespace ElectroWeakMatching {
-
- /**
- * The high energy matching
- */
- boost::numeric::ublas::matrix<Complex>
- electroWeakMatching(Energy mu, Energy2 s, Energy2 t, Energy2 u,
- Herwig::EWProcess::Process process,
- bool oneLoop,unsigned int iswap);
-}
-}
-
-#endif // HERWIG_ElectroWeakMatching_H
diff --git a/MatrixElement/EW/ElectroWeakReweighter.cc b/MatrixElement/EW/ElectroWeakReweighter.cc
deleted file mode 100644
--- a/MatrixElement/EW/ElectroWeakReweighter.cc
+++ /dev/null
@@ -1,1994 +0,0 @@
-// -*- C++ -*-
-//
-// This is the implementation of the non-inlined, non-templated member
-// functions of the ElectroWeakReweighter class.
-//
-
-#include "ElectroWeakReweighter.h"
-#include "ThePEG/Interface/ClassDocumentation.h"
-#include "ThePEG/Interface/Reference.h"
-#include "ThePEG/Interface/Switch.h"
-#include "ThePEG/EventRecord/Particle.h"
-#include "ThePEG/Repository/UseRandom.h"
-#include "ThePEG/Repository/EventGenerator.h"
-#include "ThePEG/Utilities/DescribeClass.h"
-#include "ThePEG/Persistency/PersistentOStream.h"
-#include "ThePEG/Persistency/PersistentIStream.h"
-#include "boost/numeric/ublas/matrix.hpp"
-#include "boost/numeric/ublas/operation.hpp"
-#include "EWProcess.h"
-#include "HighEnergyMatching.h"
-#include "ElectroWeakMatching.h"
-#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
-#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
-#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
-#include "ThePEG/Helicity/epsilon.h"
-#include "Herwig/MatrixElement/Matchbox/Base/SubtractedME.h"
-#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
-#include "ThePEG/Handlers/StandardXComb.h"
-
-using namespace Herwig;
-
-tEWCouplingsPtr ElectroWeakReweighter::staticEWCouplings_ = tEWCouplingsPtr();
-
-
-ElectroWeakReweighter::ElectroWeakReweighter() : testing_(false)
-{}
-
-ElectroWeakReweighter::~ElectroWeakReweighter() {}
-
-IBPtr ElectroWeakReweighter::clone() const {
- return new_ptr(*this);
-}
-
-IBPtr ElectroWeakReweighter::fullclone() const {
- return new_ptr(*this);
-}
-
-void ElectroWeakReweighter::persistentOutput(PersistentOStream & os) const {
- os << EWCouplings_ << collinearSudakov_ << softSudakov_ << testing_;
-}
-
-void ElectroWeakReweighter::persistentInput(PersistentIStream & is, int) {
- is >> EWCouplings_ >> collinearSudakov_ >> softSudakov_ >> testing_;
-}
-
-
-// The following static variable is needed for the type
-// description system in ThePEG.
-DescribeClass<ElectroWeakReweighter,ReweightBase>
-describeHerwigElectroWeakReweighter("Herwig::ElectroWeakReweighter", "HwMEEW.so");
-
-void ElectroWeakReweighter::Init() {
-
- static ClassDocumentation<ElectroWeakReweighter> documentation
- ("There is no documentation for the ElectroWeakReweighter class");
-
- static Reference<ElectroWeakReweighter,EWCouplings> interfaceEWCouplings
- ("EWCouplings",
- "The object to calculate the electroweak couplings",
- &ElectroWeakReweighter::EWCouplings_, false, false, true, false, false);
-
- static Reference<ElectroWeakReweighter,CollinearSudakov> interfaceCollinearSudakov
- ("CollinearSudakov",
- "The collinear Sudakov",
- &ElectroWeakReweighter::collinearSudakov_, false, false, true, false, false);
-
- static Reference<ElectroWeakReweighter,SoftSudakov> interfaceSoftSudakov
- ("SoftSudakov",
- "The soft Sudakov",
- &ElectroWeakReweighter::softSudakov_, false, false, true, false, false);
-
- static Switch<ElectroWeakReweighter,bool> interfaceTesting
- ("Testing",
- "Whether or not to output testing information",
- &ElectroWeakReweighter::testing_, false, false, false);
- static SwitchOption interfaceTestingYes
- (interfaceTesting,
- "Yes",
- "Output the information",
- true);
- static SwitchOption interfaceTestingNo
- (interfaceTesting,
- "No",
- "Don't output the information",
- false);
-
-}
-
-void ElectroWeakReweighter::doinit() {
- ReweightBase::doinit();
- if(!testing_) return;
- // testing output
- cerr << "aEM\n";
- for(Energy scale=10.*GeV; scale<10*TeV; scale *= 1.1) {
- cerr << scale/GeV << " "
- << EWCouplings_->aEM(scale) << "\n";
- }
- cerr << "aS\n";
- for(Energy scale=10.*GeV; scale<10*TeV; scale *= 1.4) {
- cerr << scale/GeV << " "
- << EWCouplings_->aS(scale) << "\n";
- }
- cerr << "y_t\n";
- for(Energy scale=10.*GeV; scale<10*TeV; scale *= 1.4) {
- cerr << scale/GeV << " "
- << EWCouplings_->y_t(scale) << "\n";
- }
- cerr << "lambda\n";
- for(Energy scale=91.2*GeV; scale<10*TeV; scale *= 1.4) {
- cerr << scale/GeV << " "
- << EWCouplings_->lambda(scale) << "\n";
- }
- cerr << "vev\n";
- for(Energy scale=91.2*GeV; scale<10*TeV; scale *= 1.4) {
- cerr << scale/GeV << " "
- << EWCouplings_->vev(scale)/GeV << "\n";
- }
- collinearSudakov_->makePlots();
- Energy2 s = sqr(5000.*GeV);
- Energy2 t = -0.25*s;
- Energy2 u = -0.75*s;
- testEvolution(s,t,u);
-}
-
-namespace {
-// #ifdef ThePEG_HAS_UNITS_CHECKING
-void axpy_prod_local(const boost::numeric::ublas::matrix<Complex> & A,
- const boost::numeric::ublas::matrix<complex<InvEnergy2> > & B,
- boost::numeric::ublas::matrix<complex<InvEnergy2> > & C) {
- assert(A.size2()==B.size1());
- C.resize(A.size1(),B.size2());
- for(unsigned int ix=0;ix<A.size1();++ix) {
- for(unsigned int iy=0;iy<B.size2();++iy) {
- C(ix,iy) = ZERO;
- for(unsigned int iz=0;iz<A.size2();++iz) {
- C(ix,iy) += A(ix,iz)*B(iz,iy);
- }
- }
- }
-}
-
-void axpy_prod_local(const boost::numeric::ublas::matrix<complex<InvEnergy2> > & A,
- const boost::numeric::ublas::vector<complex<Energy2> > & B,
- boost::numeric::ublas::vector<Complex > & C) {
- assert(A.size2()==B.size());
- C.resize(A.size1());
- for(unsigned int ix=0;ix<A.size1();++ix) {
- C(ix) = ZERO;
- for(unsigned int iz=0;iz<A.size2();++iz) {
- C(ix) += Complex(A(ix,iz)*B(iz));
- }
- }
-}
-
-void axpy_prod_local(const boost::numeric::ublas::matrix<complex<InvEnergy2> > & A,
- const boost::numeric::ublas::matrix<Complex> & B,
- boost::numeric::ublas::matrix<complex<InvEnergy2> > & C) {
- assert(A.size2()==B.size1());
- C.resize(A.size1(),B.size2());
- for(unsigned int ix=0;ix<A.size1();++ix) {
- for(unsigned int iy=0;iy<B.size2();++iy) {
- C(ix,iy) = ZERO;
- for(unsigned int iz=0;iz<A.size2();++iz) {
- C(ix,iy) += A(ix,iz)*B(iz,iy);
- }
- }
- }
-}
-
-// #else
-// void axpy_prod_local(const boost::numeric::ublas::matrix<Complex> & A,
-// const boost::numeric::ublas::matrix<Complex> & B,
-// boost::numeric::ublas::matrix<Complex> & C) {
-// assert(A.size2()==B.size1());
-// C.resize(A.size1(),B.size2());
-// axpy_prod(A,B,C);
-// }
-
-// void axpy_prod_local(const boost::numeric::ublas::matrix<Complex> & A,
-// const boost::numeric::ublas::vector<Complex> & B,
-// boost::numeric::ublas::vector<Complex> & C) {
-// assert(A.size2()==B.size());
-// C.resize(A.size1());
-// axpy_prod(A,B,C);
-// }
-// #endif
-
-}
-
-double ElectroWeakReweighter::weight() const {
- EWCouplings_->initialize();
- staticEWCouplings_ = EWCouplings_;
- // cast the XComb
- Ptr<StandardXComb>::ptr sxc = dynamic_ptr_cast<Ptr<StandardXComb>::ptr>(lastXCombPtr());
- // if the Herwig XComb
- if(sxc) {
- // get information about the type of event
- Ptr<SubtractedME>::tptr subme = dynamic_ptr_cast<Ptr<SubtractedME>::tptr>(sxc->matrixElement());
- Ptr<MatchboxMEBase>::tptr me = dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(sxc->matrixElement());
- Ptr<SubtractionDipole>::tptr dipme = dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(sxc->matrixElement());
- bool isHEvent(false),isSEvent(false);
- if(subme) {
- if ( subme->realShowerSubtraction() )
- isHEvent = true;
- else if ( subme->virtualShowerSubtraction() || subme->loopSimSubtraction() )
- isSEvent = true;
- }
- // H or S event of virtual return 1.
- if(isHEvent || isSEvent || (me && me->oneLoopNoBorn()))
- return 1.;
- // cerr << "testing after type check\n";
- // cerr << "testing pointers " << subme << " " << me << " " << dipme << "\n";
- // cerr << "testing event type " << isHEvent << " " << isSEvent << " " << "\n";
- // if(subme) cerr << subme->fullName() << "\n";
- // if( me) {
- // cerr << me->fullName() << "\n";
- // cerr << me->oneLoopNoBorn() << " " << me->oneLoopNoLoops() << "\n";
- // }
- // if(dipme) cerr << dipme->fullName() << "\n";
- }
- // cerr << subProcess() << "\n";
- // cerr << *subProcess() << "\n";
- // only 2->2 processes
- if(subProcess()->outgoing().size()!=2) return 1.;
- // processes with gg initial-state
- if(subProcess()->incoming().first->id()==ParticleID::g &&
- subProcess()->incoming().second->id()==ParticleID::g) {
- if(subProcess()->outgoing()[0]->id()==ParticleID::g &&
- subProcess()->outgoing()[1]->id()==ParticleID::g)
- return 1.;
- else if(abs(subProcess()->outgoing()[0]->id())<=6 &&
- subProcess()->outgoing()[0]->id()==-subProcess()->outgoing()[1]->id()) {
- return reweightggqqbar();
- }
- else
- assert(false);
- }
- // processes with q qbar initial-state
- else if((subProcess()->incoming().first ->id() > 0 &&
- subProcess()->incoming().first ->id()<= 5 &&
- subProcess()->incoming().second->id() < 0 &&
- subProcess()->incoming().second->id()>=-5) ||
- (subProcess()->incoming().second->id() > 0 &&
- subProcess()->incoming().second->id()<= 5 &&
- subProcess()->incoming().first ->id() < 0 &&
- subProcess()->incoming().first ->id()>=-5)) {
- // identical flavour q qbar
- if(subProcess()->incoming().first ->id() == -subProcess()->incoming().second->id()) {
- // q qbar -> gg
- if(subProcess()->outgoing()[0]->id()==ParticleID::g &&
- subProcess()->outgoing()[1]->id()==ParticleID::g)
- return reweightqqbargg();
- // q qbar -> q' q'bar
- else if(subProcess()->outgoing()[0]->id() == -subProcess()->outgoing()[1]->id() &&
- abs(subProcess()->outgoing()[0]->id())<=6)
- return reweightqqbarqqbarS();
- }
- // different flavour q qbar
- else {
- if((subProcess()->outgoing()[0]->id() > 0 &&
- subProcess()->outgoing()[0]->id()<= 5 &&
- subProcess()->outgoing()[1]->id() < 0 &&
- subProcess()->outgoing()[1]->id()>=-5) ||
- (subProcess()->outgoing()[1]->id() > 0 &&
- subProcess()->outgoing()[1]->id()<= 5 &&
- subProcess()->outgoing()[0]->id() < 0 &&
- subProcess()->outgoing()[0]->id()>=-5)) {
- return reweightqqbarqqbarT();
- }
- else
- assert(false);
- }
- }
- // processes with q g initial-state
- else if((subProcess()->incoming().first ->id()> 0 &&
- subProcess()->incoming().first ->id()<=5 &&
- subProcess()->incoming().second->id()==ParticleID::g) ||
- (subProcess()->incoming().second->id()> 0 &&
- subProcess()->incoming().second->id()<=5 &&
- subProcess()->incoming().first ->id()==ParticleID::g)) {
- // qg -> qg
- if((subProcess()->outgoing()[0]->id()> 0 &&
- subProcess()->outgoing()[0]->id()<=5 &&
- subProcess()->outgoing()[1]->id()==ParticleID::g) ||
- (subProcess()->outgoing()[1]->id()> 0 &&
- subProcess()->outgoing()[1]->id()<=5 &&
- subProcess()->outgoing()[0]->id()==ParticleID::g))
- return reweightqgqg();
- // unknown
- else
- assert(false);
- }
- // processes with qbar g initial-state
- else if((subProcess()->incoming().first ->id()>=-5 &&
- subProcess()->incoming().first ->id()< 0 &&
- subProcess()->incoming().second->id()==ParticleID::g) ||
- (subProcess()->incoming().second->id()>=-5 &&
- subProcess()->incoming().second->id()< 0 &&
- subProcess()->incoming().first ->id()==ParticleID::g)) {
- if((subProcess()->outgoing()[0]->id()>=-5 &&
- subProcess()->outgoing()[0]->id()< 0 &&
- subProcess()->outgoing()[1]->id()==ParticleID::g) ||
- (subProcess()->outgoing()[1]->id()>=-5 &&
- subProcess()->outgoing()[1]->id()< 0 &&
- subProcess()->outgoing()[0]->id()==ParticleID::g))
- return reweightqbargqbarg();
- else
- assert(false);
- }
- // processes with q q initial-state
- else if( subProcess()->incoming().first ->id()> 0 &&
- subProcess()->incoming().first ->id()<=5 &&
- subProcess()->incoming().second->id()> 0 &&
- subProcess()->incoming().second->id()<=5 ) {
- if(subProcess()->outgoing()[0]->id()> 0 &&
- subProcess()->outgoing()[0]->id()<=5 &&
- subProcess()->outgoing()[1]->id()> 0 &&
- subProcess()->outgoing()[1]->id()<=5)
- return reweightqqqq();
- else
- assert(false);
- }
- // processes with qbar qbar initial-state
- else if( subProcess()->incoming().first ->id()< 0 &&
- subProcess()->incoming().first ->id()>= -5 &&
- subProcess()->incoming().second->id()< 0 &&
- subProcess()->incoming().second->id()>= -5 ) {
- if(subProcess()->outgoing()[0]->id()< 0 &&
- subProcess()->outgoing()[0]->id()>= -5 &&
- subProcess()->outgoing()[1]->id()< 0 &&
- subProcess()->outgoing()[1]->id()>= -5)
- return reweightqbarqbarqbarqbar();
- else
- assert(false);
- }
- // unknown initial-state
- else
- assert(false);
- assert(false);
- staticEWCouplings_ = tEWCouplingsPtr();
-}
-
-void ElectroWeakReweighter::testEvolution(Energy2 s,Energy2 t, Energy2 u) const {
- Energy highScale = sqrt(s);
- Energy ewScale = coupling()->mZ();
- Energy lowScale = 50.0*GeV;
- for (unsigned int i=0; i<45;++i) {
- EWProcess::Process process = (EWProcess::Process)i;
- cerr << "process " << process << "\n";
- // result for all EW and QCD SCET contributions:
- boost::numeric::ublas::matrix<complex<InvEnergy2> > highMatch_val
- = HighEnergyMatching::highEnergyMatching(highScale,s,t,u,process,true,true);
- boost::numeric::ublas::matrix<Complex> highRunning_val
- = softSudakov_->highEnergyRunning(highScale,ewScale,s,t,u,process,0);
- boost::numeric::ublas::matrix<Complex> ewMatch_val =
- ElectroWeakMatching::electroWeakMatching(ewScale,s,t,u,process,true,0);
- boost::numeric::ublas::matrix<Complex> lowRunning_val =
- softSudakov_->lowEnergyRunning(ewScale,lowScale,s,t,u,process,0);
- boost::numeric::ublas::matrix<Complex> collinearHighRunning_val =
- collinearSudakov_->highEnergyRunning(highScale,ewScale,s,process,false);
- boost::numeric::ublas::matrix<Complex> collinearEWMatch_val =
- collinearSudakov_->electroWeakMatching(ewScale,s,process,true);
- boost::numeric::ublas::matrix<Complex> collinearLowRunning_val =
- collinearSudakov_->lowEnergyRunning(ewScale,lowScale,s,process);
- boost::numeric::ublas::matrix<Complex> lowMatchTemp_val =
- boost::numeric::ublas::zero_matrix<Complex>(ewMatch_val.size1(),ewMatch_val.size2());
- for (unsigned int ii=0; ii<ewMatch_val.size1(); ++ii) {
- for (unsigned int jj=0; jj<ewMatch_val.size2(); ++jj) {
- lowMatchTemp_val(ii,jj) = collinearEWMatch_val(ii,jj)*ewMatch_val(ii,jj);
- }
- }
- boost::numeric::ublas::matrix<Complex> temp(highRunning_val.size1(),collinearHighRunning_val.size2());
- boost::numeric::ublas::axpy_prod(highRunning_val,collinearHighRunning_val,temp);
- boost::numeric::ublas::matrix<Complex> temp2(collinearLowRunning_val.size1(),lowRunning_val.size2());
- boost::numeric::ublas::axpy_prod(collinearLowRunning_val,lowRunning_val,temp2);
- boost::numeric::ublas::matrix<Complex> temp3(temp2.size1(),lowMatchTemp_val.size2());
- boost::numeric::ublas::axpy_prod(temp2,lowMatchTemp_val,temp3);
- temp2.resize(temp3.size1(),temp.size2());
- boost::numeric::ublas::axpy_prod(temp3,temp,temp2);
- boost::numeric::ublas::matrix<complex<InvEnergy2> > result(temp2.size1(),highMatch_val.size2());
- axpy_prod_local(temp2,highMatch_val,result);
- for(unsigned int ix=0;ix<result.size1();++ix) {
- for(unsigned int iy=0;iy<result.size2();++iy) {
- cerr << s*result(ix,iy) << " ";
- }
- cerr << "\n";
- }
- }
-}
-
-namespace {
-
-void SackGluonPolarizations(Lorentz5Momentum &p1,
- Lorentz5Momentum &p2,
- Lorentz5Momentum &p3,
- Lorentz5Momentum &p4,
- Energy2 s, Energy2 t, Energy2 u, Energy2 m2,
- vector<LorentzVector<Complex> > & eps3,
- vector<LorentzVector<Complex> > & eps4,
- unsigned int iopt) {
- static const Complex I(0.,1.);
- // p1 is p-, p2 is p+
- // p3 is k-, p4 is k+
- // both final-state
- if(iopt==0) {
- // swap t and u due Aneesh's defn
- Energy3 den1 = sqrt((u*t-sqr(m2))*(s-4.*m2));
- Energy3 den2 = sqrt(s*(u*t-sqr(m2)));
- LorentzVector<Complex> eps3Para = (m2+t)/den1*p1 -(m2+u)/den1*p2 +(u-t)/den1*p3;
- LorentzVector<Complex> eps3Perp = 2./den2*epsilon(p1,p2,p3);
- LorentzVector<Complex> eps4Para = (m2+t)/den1*p2 -(m2+u)/den1*p1 +(u-t)/den1*p4;
- LorentzVector<Complex> eps4Perp = 2./den2*epsilon(p1,p2,p4);
- eps3.push_back(sqrt(0.5)*(eps3Para+I*eps3Perp));
- eps3.push_back(sqrt(0.5)*(eps3Para-I*eps3Perp));
- eps4.push_back(sqrt(0.5)*(eps4Para+I*eps4Perp));
- eps4.push_back(sqrt(0.5)*(eps4Para-I*eps4Perp));
- if(m2!=ZERO) assert(false);
- }
- // both initial-state
- else if(iopt==1) {
- if(m2!=ZERO) assert(false);
- LorentzVector<Complex> eps3Para( 1., 0.,0.,0.);
- LorentzVector<Complex> eps3Perp( 0.,-1.,0.,0.);
- LorentzVector<Complex> eps4Para(-1.,0.,0., 0.);
- LorentzVector<Complex> eps4Perp( 0., 1.,0.,0.);
- eps3.push_back(sqrt(0.5)*(eps3Para+I*eps3Perp));
- eps3.push_back(sqrt(0.5)*(eps3Para-I*eps3Perp));
- eps4.push_back(sqrt(0.5)*(eps4Para+I*eps4Perp));
- eps4.push_back(sqrt(0.5)*(eps4Para-I*eps4Perp));
- }
- else if(iopt==2) {
- // rotation into the 2,3 Breit frame
- Lorentz5Momentum pa = p3-p2;
- Axis axis(pa.vect().unit());
- LorentzRotation rot;
- double sinth(sqrt(sqr(axis.x())+sqr(axis.y())));
- if ( sinth > 1.e-9 )
- rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.));
- rot.rotateX(Constants::pi);
- rot.boostZ( pa.e()/pa.vect().mag());
- Lorentz5Momentum ptemp=rot*p2;
- Boost trans = -1./ptemp.e()*ptemp.vect();
- trans.setZ(0.);
- rot.boost(trans);
- LorentzVector<Complex> eps3Para( 1., 0.,0.,0.);
- LorentzVector<Complex> eps3Perp( 0.,-1.,0.,0.);
- LorentzVector<Complex> eps4Para(-1.,0.,0., 0.);
- LorentzVector<Complex> eps4Perp( 0., 1.,0.,0.);
- eps3.push_back(sqrt(0.5)*(eps3Para+I*eps3Perp));
- eps3.push_back(sqrt(0.5)*(eps3Para-I*eps3Perp));
- eps4.push_back(sqrt(0.5)*(eps4Para+I*eps4Perp));
- eps4.push_back(sqrt(0.5)*(eps4Para-I*eps4Perp));
- rot = rot.invert();
- for(unsigned int ix=0;ix<2;++ix) {
- eps3[ix] *=rot;
- eps4[ix] *=rot;
- }
- }
- else if(iopt==3) {
- // rotation into the 1,4 Breit frame
- Lorentz5Momentum pa = p4-p1;
- Axis axis(pa.vect().unit());
- LorentzRotation rot;
- double sinth(sqrt(sqr(axis.x())+sqr(axis.y())));
- if ( sinth > 1.e-9 )
- rot.setRotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.));
- rot.rotateX(Constants::pi);
- rot.boostZ( pa.e()/pa.vect().mag());
- Lorentz5Momentum ptemp=rot*p1;
- Boost trans = -1./ptemp.e()*ptemp.vect();
- trans.setZ(0.);
- rot.boost(trans);
- LorentzVector<Complex> eps3Para( 1., 0.,0.,0.);
- LorentzVector<Complex> eps3Perp( 0.,-1.,0.,0.);
- LorentzVector<Complex> eps4Para(-1.,0.,0., 0.);
- LorentzVector<Complex> eps4Perp( 0., 1.,0.,0.);
- eps3.push_back(sqrt(0.5)*(eps3Para+I*eps3Perp));
- eps3.push_back(sqrt(0.5)*(eps3Para-I*eps3Perp));
- eps4.push_back(sqrt(0.5)*(eps4Para+I*eps4Perp));
- eps4.push_back(sqrt(0.5)*(eps4Para-I*eps4Perp));
- rot = rot.invert();
- for(unsigned int ix=0;ix<2;++ix) {
- eps3[ix] *=rot;
- eps4[ix] *=rot;
- }
- }
- else
- assert(false);
-}
-
-}
-
-double ElectroWeakReweighter::reweightqqbargg() const {
- // momenta and invariants
- Lorentz5Momentum p1 = subProcess()->incoming().first ->momentum();
- tcPDPtr q = subProcess()->incoming().first ->dataPtr();
- Lorentz5Momentum p2 = subProcess()->incoming().second->momentum();
- tcPDPtr qbar = subProcess()->incoming().second->dataPtr();
- if(subProcess()->incoming().first->id()<0) {
- swap(p1,p2 );
- swap(q ,qbar);
- }
- Lorentz5Momentum p3 = subProcess()->outgoing()[0]->momentum();
- Lorentz5Momentum p4 = subProcess()->outgoing()[1]->momentum();
- tcPDPtr g = subProcess()->outgoing()[1]->dataPtr();
- Energy2 s = (p1+p2).m2();
- Energy2 t = (p1-p4).m2();
- Energy2 u = (p1-p3).m2();
- // boost to partonci rest frame
- Lorentz5Momentum psum=p1+p2;
- LorentzRotation boost(-psum.boostVector());
- p1 *= boost;
- p2 *= boost;
- p3 *= boost;
- p4 *= boost;
- // LO and EW corrected matrix element coefficients
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- bornQQGGweights,bornRRGGweights,EWQQGGweights,EWRRGGweights;
- // quark left doublet
- if(q->id()!=5) {
- bornQQGGweights = evaluateRunning(EWProcess::QQGG,s,t,u,true ,0);
- EWQQGGweights = evaluateRunning(EWProcess::QQGG,s,t,u,false,0);
- }
- else {
- bornQQGGweights = evaluateRunning(EWProcess::QtQtGG,s,t,u,true ,0);
- EWQQGGweights = evaluateRunning(EWProcess::QtQtGG,s,t,u,false,0);
- }
- // quark right singlet
- if(abs(subProcess()->incoming().first->id())%2==0) {
- bornRRGGweights = evaluateRunning(EWProcess::UUGG,s,t,u,true ,0);
- EWRRGGweights = evaluateRunning(EWProcess::UUGG,s,t,u,false,0);
- }
- else {
- bornRRGGweights = evaluateRunning(EWProcess::DDGG,s,t,u,true ,0);
- EWRRGGweights = evaluateRunning(EWProcess::DDGG,s,t,u,false,0);
- }
- SpinorWaveFunction qw(p1,q ,incoming);
- SpinorBarWaveFunction qbarw(p2,qbar,incoming);
- vector<LorentzVector<Complex> > eps3,eps4;
- SackGluonPolarizations(p1,p2,p3,p4,s,t,u,ZERO,eps3,eps4,0);
- boost::numeric::ublas::matrix<Complex>
- bornME = boost::numeric::ublas::zero_matrix<Complex>(3,3),
- EWME = boost::numeric::ublas::zero_matrix<Complex>(3,3);
- for(unsigned int iq=0;iq<2;++iq) {
- if(iq==0) {
- qw.reset (0);
- qbarw.reset(1);
- }
- else {
- qw.reset (1);
- qbarw.reset(0);
- }
- LorentzVector<complex<Energy> > current = iq==0 ?
- qw.dimensionedWave(). leftCurrent(qbarw.dimensionedWave()) :
- qw.dimensionedWave().rightCurrent(qbarw.dimensionedWave());
- for(unsigned int i1=0;i1<2;++i1) {
- complex<Energy> d31 = eps3[i1].dot(p1);
- LorentzVector<complex<Energy2> >
- temp = qw.dimensionedWave().slash(eps3[i1]).slash(p4-p2).vectorCurrent(qbarw.dimensionedWave());
- for(unsigned int i2=0;i2<2;++i2) {
- boost::numeric::ublas::vector<complex<Energy2> > M(5);
- Complex d34 = eps3[i1].dot(eps4[i2]);
- complex<Energy> d42 = eps4[i2].dot(p2);
- // M0 in paper
- M(0) = temp.dot(eps4[i2]);
- // M4 in paper
- M(2) = current.dot(eps4[i2])*d31;
- // M5 in paper
- M(3) = -current.dot(eps3[i1])*d42;
- // M1 in paper (missing factor)
- M(1) = current.dot(p4);
- // M6 in paper
- M(4) = M(1)*d31*d42/GeV2;
- // M1 final factor
- M(1) *= d34;
- // coefficient of different contributions
- boost::numeric::ublas::vector<Complex> Cborn(3),CEW(3),Ctest(3);
-
-
- // Ctest(0) = 1./6.*( MEU+MET);
- // Ctest(1) = 0.5*( MEU+MET);
- // Ctest(2) = 0.5*(MEU+MES-MET+MES);
- if(iq==0) {
- axpy_prod_local(bornQQGGweights,M,Cborn);
- axpy_prod_local(EWQQGGweights ,M,CEW );
- }
- else {
- axpy_prod_local(bornRRGGweights,M,Cborn);
- axpy_prod_local(EWRRGGweights ,M,CEW );
- }
- unsigned int ioff = (Cborn.size()==6 && q->id()%2!=0) ? 3 : 0;
- for(unsigned int ix=0;ix<3;++ix) {
- for(unsigned int iy=0;iy<3;++iy) {
- bornME(ix,iy) += Cborn(ix+ioff)*conj(Cborn(iy+ioff));
- EWME (ix,iy) += CEW (ix+ioff)*conj(CEW (iy+ioff));
- }
- }
- }
- }
- }
- double born = 24.*real(bornME(0,0))+20./3.*real(bornME(1,1))+12.*real(bornME(2,2));
- double EW = 24.*real(EWME(0,0))+20./3.*real(EWME(1,1))+12.*real(EWME(2,2));
- return EW/born;
-}
-
-boost::numeric::ublas::matrix<complex<InvEnergy2> >
-ElectroWeakReweighter::evaluateRunning(EWProcess::Process process, Energy2 s,
- Energy2 t, Energy2 u, bool born,
- unsigned int iswap) const {
- using namespace boost::numeric::ublas;
- bool SU3save = coupling()->SU3();
- bool EWsave = coupling()-> EW();
- Energy highScale = sqrt(s);
- Energy ewScale = coupling()->mZ();
- Energy lowScale = ewScale;
- // result for all EW and QCD SCET contributions:
- // MATCHING CONTRIBUTIONS
- // high energy matching
- matrix<complex<InvEnergy2> > highMatch_val;
- if(iswap==0)
- highMatch_val = HighEnergyMatching::highEnergyMatching(highScale,s,t,u,process,!born,false);
- else if(iswap==1)
- highMatch_val = HighEnergyMatching::highEnergyMatching(highScale,t,s,u,process,!born,false);
- else if(iswap==2)
- highMatch_val = HighEnergyMatching::highEnergyMatching(highScale,u,t,s,process,!born,false);
- else
- assert(false);
- // low energy matching
- matrix<Complex>
- ewMatch_val = ElectroWeakMatching::electroWeakMatching(ewScale,s,t,u,process,!born,iswap);
- matrix<Complex> collinearEWMatch_val =
- collinearSudakov_->electroWeakMatching(ewScale,s,process,!born);
- // EVOLUTION
- matrix<Complex> highRunning_val,lowRunning_val,
- collinearHighRunning_val,collinearLowRunning_val;
- // born process
- if(born) {
- highRunning_val = identity_matrix<Complex>(softSudakov_->numberGauge(process));
- lowRunning_val = identity_matrix<Complex>(softSudakov_->numberBrokenGauge(process));
- collinearHighRunning_val = identity_matrix<Complex>(softSudakov_->numberGauge(process));
- collinearLowRunning_val = identity_matrix<Complex>(softSudakov_->numberBrokenGauge(process));
- }
- // EW corrected
- else {
- coupling()->SU3(false);
- coupling()-> EW( true);
- highRunning_val = softSudakov_->highEnergyRunning(highScale, ewScale,s,t,u,process,iswap);
- lowRunning_val = softSudakov_->lowEnergyRunning ( ewScale,lowScale,s,t,u,process,iswap);
- collinearHighRunning_val = collinearSudakov_->highEnergyRunning(highScale,ewScale,s,process,false);
- collinearLowRunning_val = collinearSudakov_->lowEnergyRunning(ewScale,lowScale,s,process);
- };
- matrix<Complex> lowMatchTemp_val =
- zero_matrix<Complex>(ewMatch_val.size1(),ewMatch_val.size2());
- for (unsigned int ii=0; ii<ewMatch_val.size1(); ++ii) {
- for (unsigned int jj=0; jj<ewMatch_val.size2(); ++jj) {
- lowMatchTemp_val(ii,jj) = collinearEWMatch_val(ii,jj)*ewMatch_val(ii,jj);
- }
- }
- // perform all the multiplications
- matrix<Complex> temp(highRunning_val.size1(),collinearHighRunning_val.size2());
- axpy_prod(highRunning_val,collinearHighRunning_val,temp);
- matrix<Complex> temp2(collinearLowRunning_val.size1(),lowRunning_val.size2());
- axpy_prod(collinearLowRunning_val,lowRunning_val,temp2);
- matrix<Complex> temp3(temp2.size1(),lowMatchTemp_val.size2());
- axpy_prod(temp2,lowMatchTemp_val,temp3);
- temp2.resize(temp3.size1(),temp.size2());
- axpy_prod(temp3,temp,temp2);
- matrix<complex<InvEnergy2> > result(temp2.size1(),highMatch_val.size2());
- axpy_prod_local(temp2,highMatch_val,result);
- // reset the couplings
- coupling()->SU3(SU3save);
- coupling()-> EW( EWsave);
- // return the answer
- return result;
-}
-
-
-double ElectroWeakReweighter::reweightggqqbar() const {
- // momenta and invariants
- Lorentz5Momentum p1 = subProcess()->incoming().first ->momentum();
- Lorentz5Momentum p2 = subProcess()->incoming().second->momentum();
- Lorentz5Momentum p3 = subProcess()->outgoing()[0]->momentum();
- Lorentz5Momentum p4 = subProcess()->outgoing()[1]->momentum();
- tcPDPtr qbar = subProcess()->outgoing()[0]->dataPtr();
- tcPDPtr q = subProcess()->outgoing()[1]->dataPtr();
- if(q->id()<0) {
- swap(p3,p4 );
- swap(q ,qbar);
- }
- Energy2 s = (p1+p2).m2();
- Energy2 t = (p1-p4).m2();
- Energy2 u = (p1-p3).m2();
- // boost to partonic rest frame and rescale momenta of outgoing
- // so zero mass
- Lorentz5Momentum psum=p1+p2;
- LorentzRotation boost(-psum.boostVector());
- p1 *= boost;
- p2 *= boost;
- p3 *= boost;
- p4 *= boost;
- p3.setMass(ZERO);
- p3.rescaleRho();
- p4.setMass(ZERO);
- p4.rescaleRho();
- // LO and EW matrix element coefficents
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- bornQQGGweights,bornRRGGweights,EWQQGGweights,EWRRGGweights;
- // quark left doublet
- if(q->id()<5) {
- bornQQGGweights = evaluateRunning(EWProcess::QQGG,s,t,u,true ,0);
- EWQQGGweights = evaluateRunning(EWProcess::QQGG,s,t,u,false,0);
- }
- else {
- bornQQGGweights = evaluateRunning(EWProcess::QtQtGG,s,t,u,true ,0);
- EWQQGGweights = evaluateRunning(EWProcess::QtQtGG,s,t,u,false,0);
- }
- // quark right singlet
- if(q->id()==0) {
- if(q->id()==6) {
- bornRRGGweights = evaluateRunning(EWProcess::tRtRGG,s,t,u,true ,0);
- EWRRGGweights = evaluateRunning(EWProcess::tRtRGG,s,t,u,false,0);
- }
- else {
- bornRRGGweights = evaluateRunning(EWProcess::UUGG,s,t,u,true ,0);
- EWRRGGweights = evaluateRunning(EWProcess::UUGG,s,t,u,false,0);
- }
- }
- else {
- bornRRGGweights = evaluateRunning(EWProcess::DDGG,s,t,u,true ,0);
- EWRRGGweights = evaluateRunning(EWProcess::DDGG,s,t,u,false,0);
- }
- SpinorWaveFunction qw(p4,qbar,incoming);
- SpinorBarWaveFunction qbarw(p3,q ,incoming);
- vector<LorentzVector<Complex> > eps1,eps2;
- SackGluonPolarizations(p1,p2,p3,p4,s,t,u,ZERO,eps1,eps2,1);
- boost::numeric::ublas::matrix<Complex>
- bornME = boost::numeric::ublas::zero_matrix<Complex>(3,3),
- EWME = boost::numeric::ublas::zero_matrix<Complex>(3,3);
- // helicities of outgoing quarks
- for(unsigned int iq=0;iq<2;++iq) {
- if(iq==0) {
- qw.reset (0);
- qbarw.reset(1);
- }
- else {
- qw.reset (1);
- qbarw.reset(0);
- }
- LorentzVector<complex<Energy> > current = iq==0 ?
- qw.dimensionedWave(). leftCurrent(qbarw.dimensionedWave()) :
- qw.dimensionedWave().rightCurrent(qbarw.dimensionedWave());
- for(unsigned int i1=0;i1<2;++i1) {
- complex<Energy> d31 = eps1[i1].dot(p3);
- LorentzVector<complex<Energy2> > temp =
- qw.dimensionedWave().slash(eps1[i1])
- .slash(p2-p4).vectorCurrent(qbarw.dimensionedWave());
- for(unsigned int i2=0;i2<2;++i2) {
- boost::numeric::ublas::vector<complex<Energy2> > M(5);
- Complex d34 = eps1[i1].dot(eps2[i2]);
- complex<Energy> d42 = eps2[i2].dot(p4);
- // M0 in paper
- M(0) = temp.dot(eps2[i2]);
- // M4 in paper
- M(2) = current.dot(eps2[i2])*d31;
- // M5 in paper
- M(3) = -current.dot(eps1[i1])*d42;
- // M1 in paper (missing factor)
- M(1) = current.dot(p2);
- // M6 in paper
- M(4) = M(1)*d31*d42/GeV2;
- // M1 final factor
- M(1) *= d34;
- // coefficient of different contributions
- boost::numeric::ublas::vector<Complex> Cborn(3),CEW(3);
- if(iq==0) {
- axpy_prod_local(bornQQGGweights,M,Cborn);
- axpy_prod_local(EWQQGGweights ,M,CEW );
- }
- else {
- axpy_prod_local(bornRRGGweights,M,Cborn);
- axpy_prod_local(EWRRGGweights ,M,CEW );
- }
- unsigned int ioff = (Cborn.size()==6 && q->id()%2!=0) ? 3 : 0;
- for(unsigned int ix=0;ix<3;++ix) {
- for(unsigned int iy=0;iy<3;++iy) {
- bornME(ix,iy) += Cborn(ix+ioff)*conj(Cborn(iy+ioff));
- EWME (ix,iy) += CEW (ix+ioff)*conj(CEW (iy+ioff));
- }
- }
- }
- }
- }
- double born = 24.*real(bornME(0,0))+20./3.*real(bornME(1,1))+12.*real(bornME(2,2));
- double EW = 24.*real(EWME(0,0))+20./3.*real(EWME(1,1))+12.*real(EWME(2,2));
- return EW/born;
-}
-
-double ElectroWeakReweighter::reweightqgqg() const {
- // momenta and invariants
- Lorentz5Momentum p1 = subProcess()->incoming().first ->momentum();
- Lorentz5Momentum p2 = subProcess()->incoming().second->momentum();
- tcPDPtr q;
- if(subProcess()->incoming().first->id()!=ParticleID::g) {
- q = subProcess()->incoming().first ->dataPtr();
- }
- else {
- q = subProcess()->incoming().second->dataPtr();
- swap(p1,p2);
- }
- Lorentz5Momentum p3 = subProcess()->outgoing()[0]->momentum();
- Lorentz5Momentum p4 = subProcess()->outgoing()[1]->momentum();
- if(subProcess()->outgoing()[0]->id()!=ParticleID::g)
- swap(p3,p4);
- Energy2 s = (p1+p2).m2();
- Energy2 t = (p1-p4).m2();
- Energy2 u = (p1-p3).m2();
- // boost to partonic rest frame
- Lorentz5Momentum psum=p1+p2;
- LorentzRotation boost(-psum.boostVector());
- p1 *= boost;
- p2 *= boost;
- p3 *= boost;
- p4 *= boost;
- // LO and EW corrected matrix element coefficients
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- bornQQGGweights,bornRRGGweights,EWQQGGweights,EWRRGGweights;
- // quark left doublet
- if(q->id()!=5) {
- bornQQGGweights = evaluateRunning(EWProcess::QQGG,s,t,u,true ,1);
- EWQQGGweights = evaluateRunning(EWProcess::QQGG,s,t,u,false,1);
- }
- else {
- bornQQGGweights = evaluateRunning(EWProcess::QtQtGG,s,t,u,true ,1);
- EWQQGGweights = evaluateRunning(EWProcess::QtQtGG,s,t,u,false,1);
- }
- // quark right singlet
- if(abs(q->id())%2==0) {
- bornRRGGweights = evaluateRunning(EWProcess::UUGG,s,t,u,true ,1);
- EWRRGGweights = evaluateRunning(EWProcess::UUGG,s,t,u,false,1);
- }
- else {
- bornRRGGweights = evaluateRunning(EWProcess::DDGG,s,t,u,true ,1);
- EWRRGGweights = evaluateRunning(EWProcess::DDGG,s,t,u,false,1);
- }
- SpinorWaveFunction qw(p1,q,incoming);
- SpinorBarWaveFunction qbarw(p4,q,outgoing);
- vector<LorentzVector<Complex> > eps2,eps3;
- SackGluonPolarizations(p1,p2,p3,p4,s,t,u,ZERO,eps2,eps3,2);
- // compute the matrix elements
- boost::numeric::ublas::matrix<Complex>
- bornME = boost::numeric::ublas::zero_matrix<Complex>(3,3),
- EWME = boost::numeric::ublas::zero_matrix<Complex>(3,3),
- testME = boost::numeric::ublas::zero_matrix<Complex>(3,3);
- for(unsigned int iq=0;iq<2;++iq) {
- if(iq==0) {
- qw.reset (0);
- qbarw.reset(0);
- }
- else {
- qw.reset (1);
- qbarw.reset(1);
- }
- LorentzVector<complex<Energy> > current = iq==0 ?
- qw.dimensionedWave(). leftCurrent(qbarw.dimensionedWave()) :
- qw.dimensionedWave().rightCurrent(qbarw.dimensionedWave());
- for(unsigned int i1=0;i1<2;++i1) {
- complex<Energy> d31 = eps3[i1].dot(p1);
- LorentzVector<complex<Energy2 >> temp =
- qw.dimensionedWave().slash(eps3[i1])
- .slash(p2-p4).vectorCurrent(qbarw.dimensionedWave());
- for(unsigned int i2=0;i2<2;++i2) {
- boost::numeric::ublas::vector<complex<Energy2> > M(5);
- Complex d34 = eps3[i1].dot(eps2[i2]);
- complex<Energy> d42 = eps2[i2].dot(p4);
- // M0 in paper
- M(0) = temp.dot(eps2[i2]);
- // M4 in paper
- M(2) = current.dot(eps2[i2])*d31;
- // M5 in paper
- M(3) = -current.dot(eps3[i1])*d42;
- // M1 in paper (missing factor)
- M(1) = current.dot(p2);
- // M6 in paper
- M(4) = M(1)*d31*d42/GeV2;
- // M1 final factor
- M(1) *= d34;
- // coefficient of different contributions
- boost::numeric::ublas::vector<Complex> Cborn(3),CEW(3);
- if(iq==0) {
- axpy_prod_local(bornQQGGweights,M,Cborn);
- axpy_prod_local(EWQQGGweights ,M,CEW );
- }
- else {
- axpy_prod_local(bornRRGGweights,M,Cborn);
- axpy_prod_local(EWRRGGweights ,M,CEW );
- }
- unsigned int ioff = (Cborn.size()==6 && q->id()%2!=0) ? 3 : 0;
- for(unsigned int ix=0;ix<3;++ix) {
- for(unsigned int iy=0;iy<3;++iy) {
- bornME(ix,iy) += Cborn(ix+ioff)*conj(Cborn(iy+ioff));
- EWME (ix,iy) += CEW (ix+ioff)*conj(CEW (iy+ioff));
- }
- }
- }
- }
- }
- double born = 24.*real(bornME(0,0))+20./3.*real(bornME(1,1))+12.*real(bornME(2,2));
- double EW = 24.*real(EWME(0,0))+20./3.*real(EWME(1,1))+12.*real(EWME(2,2));
- return EW/born;
-}
-
-double ElectroWeakReweighter::reweightqbargqbarg() const {
- // momenta and invariants
- Lorentz5Momentum p1 = subProcess()->incoming().first ->momentum();
- Lorentz5Momentum p2 = subProcess()->incoming().second->momentum();
- tcPDPtr qbar;
- if(subProcess()->incoming().first->id()==ParticleID::g) {
- qbar = subProcess()->incoming().second->dataPtr();
- }
- else {
- qbar = subProcess()->incoming().first ->dataPtr();
- swap(p1,p2);
- }
- Lorentz5Momentum p3 = subProcess()->outgoing()[0]->momentum();
- Lorentz5Momentum p4 = subProcess()->outgoing()[1]->momentum();
- if(subProcess()->outgoing()[0]->id()==ParticleID::g)
- swap(p3,p4);
- Energy2 s = (p1+p2).m2();
- Energy2 t = (p1-p4).m2();
- Energy2 u = (p1-p3).m2();
- // boost to partonci rest frame
- Lorentz5Momentum psum=p1+p2;
- LorentzRotation boost(-psum.boostVector());
- p1 *= boost;
- p2 *= boost;
- p3 *= boost;
- p4 *= boost;
- // LO and EW corrected matrix element coefficients
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- bornQQGGweights,bornRRGGweights,EWQQGGweights,EWRRGGweights;
- // quark left doublet
- if(qbar->id()!=-5) {
- bornQQGGweights = evaluateRunning(EWProcess::QQGG,s,t,u,true ,1);
- EWQQGGweights = evaluateRunning(EWProcess::QQGG,s,t,u,false,1);
- }
- else {
- bornQQGGweights = evaluateRunning(EWProcess::QtQtGG,s,t,u,true ,1);
- EWQQGGweights = evaluateRunning(EWProcess::QtQtGG,s,t,u,false,1);
- }
- // quark right singlet
- if(abs(qbar->id())%2==0) {
- bornRRGGweights = evaluateRunning(EWProcess::UUGG,s,t,u,true ,1);
- EWRRGGweights = evaluateRunning(EWProcess::UUGG,s,t,u,false,1);
- }
- else {
- bornRRGGweights = evaluateRunning(EWProcess::DDGG,s,t,u,true ,1);
- EWRRGGweights = evaluateRunning(EWProcess::DDGG,s,t,u,false,1);
- }
- SpinorWaveFunction qw(p3,qbar,outgoing);
- SpinorBarWaveFunction qbarw(p2,qbar,incoming);
- vector<LorentzVector<Complex> > eps1,eps4;
- SackGluonPolarizations(p1,p2,p3,p4,s,t,u,ZERO,eps1,eps4,3);
- boost::numeric::ublas::matrix<Complex>
- bornME = boost::numeric::ublas::zero_matrix<Complex>(3,3),
- EWME = boost::numeric::ublas::zero_matrix<Complex>(3,3);
- for(unsigned int iq=0;iq<2;++iq) {
- if(iq==0) {
- qw.reset (1);
- qbarw.reset(1);
- }
- else {
- qw.reset (0);
- qbarw.reset(0);
- }
- LorentzVector<complex<Energy> > current = iq==0 ?
- qw.dimensionedWave(). leftCurrent(qbarw.dimensionedWave()) :
- qw.dimensionedWave().rightCurrent(qbarw.dimensionedWave());
- for(unsigned int i1=0;i1<2;++i1) {
- complex<Energy> d31 = eps1[i1].dot(p3);
- LorentzVector<complex<Energy2> > temp =
- qw.dimensionedWave().slash(eps1[i1])
- .slash(p4-p2).vectorCurrent(qbarw.dimensionedWave());
- for(unsigned int i2=0;i2<2;++i2) {
- boost::numeric::ublas::vector<complex<Energy2> > M(5);
- Complex d34 = eps1[i1].dot(eps4[i2]);
- complex<Energy> d42 = eps4[i2].dot(p2);
- // M0 in paper
- M(0) = temp.dot(eps4[i2]);
- // M4 in paper
- M(2) = current.dot(eps4[i2])*d31;
- // M5 in paper
- M(3) = -current.dot(eps1[i1])*d42;
- // M1 in paper (missing factor)
- M(1) = current.dot(p4);
- // M6 in paper
- M(4) = M(1)*d31*d42/GeV2;
- // M1 final factor
- M(1) *= d34;
- // coefficient of different contributions
- boost::numeric::ublas::vector<Complex> Cborn(3),CEW(3);
- if(iq==0) {
- axpy_prod_local(bornQQGGweights,M,Cborn);
- axpy_prod_local(EWQQGGweights ,M,CEW );
- }
- else {
- axpy_prod_local(bornRRGGweights,M,Cborn);
- axpy_prod_local(EWRRGGweights ,M,CEW );
- }
- unsigned int ioff = (Cborn.size()==6 && abs(qbar->id())%2!=0) ? 3 : 0;
- for(unsigned int ix=0;ix<3;++ix) {
- for(unsigned int iy=0;iy<3;++iy) {
- bornME(ix,iy) += Cborn(ix+ioff)*conj(Cborn(iy+ioff));
- EWME (ix,iy) += CEW (ix+ioff)*conj(CEW (iy+ioff));
- }
- }
- }
- }
- }
- double born = 24.*real(bornME(0,0))+20./3.*real(bornME(1,1))+12.*real(bornME(2,2));
- double EW = 24.*real(EWME(0,0))+20./3.*real(EWME(1,1))+12.*real(EWME(2,2));
- return EW/born;
-}
-
-double ElectroWeakReweighter::reweightqqbarqqbarS() const {
- // momenta and invariants
- Lorentz5Momentum p1 = subProcess()->incoming().first ->momentum();
- tcPDPtr q1 = subProcess()->incoming().first ->dataPtr();
- Lorentz5Momentum p2 = subProcess()->incoming().second->momentum();
- tcPDPtr q1bar = subProcess()->incoming().second->dataPtr();
- if(q1->id()<0) {
- swap(p1,p2 );
- swap(q1 ,q1bar);
- }
- Lorentz5Momentum p3 = subProcess()->outgoing()[0]->momentum();
- tcPDPtr q2bar = subProcess()->outgoing()[0]->dataPtr();
- Lorentz5Momentum p4 = subProcess()->outgoing()[1]->momentum();
- tcPDPtr q2 = subProcess()->outgoing()[1]->dataPtr();
- if(q2bar->id()>0) {
- swap(p3,p4 );
- swap(q2 ,q2bar);
- }
- Energy2 s = (p1+p2).m2();
- Energy2 t = (p1-p4).m2();
- Energy2 u = (p1-p3).m2();
- // boost to partonci rest frame
- Lorentz5Momentum psum=p1+p2;
- LorentzRotation boost(-psum.boostVector());
- p1 *= boost;
- p2 *= boost;
- p3 *= boost;
- p4 *= boost;
- p3.setMass(ZERO);
- p3.rescaleRho();
- p4.setMass(ZERO);
- p4.rescaleRho();
- // LO and EW corrected matrix element coefficients
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- bornLLLLWeights,bornLLRRWeights,bornRRLLWeights,bornRRRRWeights,
- EWLLLLWeights,EWLLRRWeights,EWRRLLWeights,EWRRRRWeights;
- bool ident = q1->id()==q2->id();
- // LL -> LL
- if((q1->id()<=4&& q2->id()<=4)|| (q1->id()==5 && q2->id()==5)) {
- if(!ident) {
- bornLLLLWeights = evaluateRunning(EWProcess::QQQQ,s,t,u,true ,0);
- EWLLLLWeights = evaluateRunning(EWProcess::QQQQ,s,t,u,false,0);
- }
- else {
- bornLLLLWeights = evaluateRunning(EWProcess::QQQQiden,s,t,u,true ,0);
- EWLLLLWeights = evaluateRunning(EWProcess::QQQQiden,s,t,u,false,0);
- }
- }
- else if(q1->id()==5 || q2->id()>=5) {
- bornLLLLWeights = evaluateRunning(EWProcess::QtQtQQ,s,t,u,true ,0);
- EWLLLLWeights = evaluateRunning(EWProcess::QtQtQQ,s,t,u,false,0);
- }
- else
- assert(false);
- // RR -> LL
- if(q1->id()%2==0) {
- if(q2->id()<5) {
- bornRRLLWeights = evaluateRunning(EWProcess::QQUU,s,t,u,true ,0);
- EWRRLLWeights = evaluateRunning(EWProcess::QQUU,s,t,u,false,0);
- }
- else {
- bornRRLLWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,true ,0);
- EWRRLLWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,false,0);
- }
- }
- else {
- if(q2->id()<5) {
- bornRRLLWeights = evaluateRunning(EWProcess::QQDD,s,t,u,true ,0);
- EWRRLLWeights = evaluateRunning(EWProcess::QQDD,s,t,u,false,0);
- }
- else {
- bornRRLLWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,true ,0);
- EWRRLLWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,false,0);
- }
- }
- // LL -> RR
- if(q1->id()<=4) {
- if(q2->id()%2!=0) {
- bornLLRRWeights = evaluateRunning(EWProcess::QQDD,s,t,u,true ,0);
- EWLLRRWeights = evaluateRunning(EWProcess::QQDD,s,t,u,false,0);
- }
- else if (q2->id()==6) {
- bornLLRRWeights = evaluateRunning(EWProcess::QQtRtR,s,t,u,true ,0);
- EWLLRRWeights = evaluateRunning(EWProcess::QQtRtR,s,t,u,false,0);
- }
- else {
- bornLLRRWeights = evaluateRunning(EWProcess::QQUU,s,t,u,true ,0);
- EWLLRRWeights = evaluateRunning(EWProcess::QQUU,s,t,u,false,0);
- }
- }
- else {
- if(q2->id()%2!=0) {
- bornLLRRWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,true ,0);
- EWLLRRWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,false,0);
- }
- else {
- bornLLRRWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,true ,0);
- EWLLRRWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,false,0);
- }
- }
- // RR -> RR
- if(q1->id()%2==0) {
- if(q2->id()==6) {
- bornRRRRWeights = evaluateRunning(EWProcess::tRtRUU,s,t,u,true ,0);
- EWRRRRWeights = evaluateRunning(EWProcess::tRtRUU,s,t,u,false,0);
- }
- else if(q2->id()%2==0) {
- if(ident) {
- bornRRRRWeights = evaluateRunning(EWProcess::UUUUiden,s,t,u,true ,0);
- EWRRRRWeights = evaluateRunning(EWProcess::UUUUiden,s,t,u,false,0);
- }
- else {
- bornRRRRWeights = evaluateRunning(EWProcess::UUUU,s,t,u,true ,0);
- EWRRRRWeights = evaluateRunning(EWProcess::UUUU,s,t,u,false,0);
- }
- }
- else {
- bornRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,true ,0);
- EWRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,false,0);
- }
- }
- else {
- if(q2->id()==6) {
- bornRRRRWeights = evaluateRunning(EWProcess::tRtRDD,s,t,u,true ,0);
- EWRRRRWeights = evaluateRunning(EWProcess::tRtRDD,s,t,u,false,0);
- }
- else if(q2->id()%2==0) {
- bornRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,true ,0);
- EWRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,false,0);
- }
- else {
- if(ident) {
- bornRRRRWeights = evaluateRunning(EWProcess::DDDDiden,s,t,u,true ,0);
- EWRRRRWeights = evaluateRunning(EWProcess::DDDDiden,s,t,u,false,0);
- }
- else {
- bornRRRRWeights = evaluateRunning(EWProcess::DDDD,s,t,u,true ,0);
- EWRRRRWeights = evaluateRunning(EWProcess::DDDD,s,t,u,false,0);
- }
- }
- }
- // extra terms for identical particles
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- borntChannelWeights,EWtChannelWeights;
- if(ident) {
- if(q1->id()%2==0) {
- borntChannelWeights = evaluateRunning(EWProcess::QQUU,s,t,u,true ,1);
- EWtChannelWeights = evaluateRunning(EWProcess::QQUU,s,t,u,false,1);
- }
- else if(q1->id()==5) {
- borntChannelWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,true ,1);
- EWtChannelWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,false,1);
- }
- else {
- borntChannelWeights = evaluateRunning(EWProcess::QQDD,s,t,u,true ,1);
- EWtChannelWeights = evaluateRunning(EWProcess::QQDD,s,t,u,false,1);
- }
- }
- SpinorWaveFunction q1w(p1,q1 ,incoming);
- SpinorBarWaveFunction q1barw(p2,q1bar,incoming);
- SpinorWaveFunction q2barw(p3,q2bar,outgoing);
- SpinorBarWaveFunction q2w(p4,q2 ,outgoing);
- boost::numeric::ublas::matrix<Complex>
- bornME = boost::numeric::ublas::zero_matrix<Complex>(2,2),
- EWME = boost::numeric::ublas::zero_matrix<Complex>(2,2);
- for(unsigned int iq1=0;iq1<2;++iq1) {
- if(iq1==0) {
- q1w.reset (0);
- q1barw.reset(1);
- }
- else {
- q1w.reset (1);
- q1barw.reset(0);
- }
- LorentzVector<complex<Energy> > current1 =
- q1w.dimensionedWave().vectorCurrent(q1barw.dimensionedWave());
- for(unsigned int iq2=0;iq2<2;++iq2) {
- if(iq2==0) {
- q2w.reset (0);
- q2barw.reset(1);
- }
- else {
- q2w.reset (1);
- q2barw.reset(0);
- }
- LorentzVector<complex<Energy> > current2 =
- q2barw.dimensionedWave().vectorCurrent(q2w.dimensionedWave());
- complex<Energy2> amp = current1.dot(current2);
- vector<Complex> Cborn(2),CEW(2);
- // amplitudes
- if(iq1==0) {
- // LL
- if(iq2==0) {
- unsigned int ioff;
- if(q1->id()%2==0) {
- ioff = q2->id()%2==0 ? 0 : 2;
- }
- else {
- ioff = q2->id()%2==0 ? 1 : 3;
- }
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornLLLLWeights(6*ix+ioff,0));
- CEW [ix] = Complex(amp* EWLLLLWeights(6*ix+ioff,0));
- }
- }
- // LR
- else {
- unsigned int ioff = q1->id()%2==0 ? 0 : 1;
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornLLRRWeights(2*ix+ioff,0));
- CEW [ix] = Complex(amp* EWLLRRWeights(2*ix+ioff,0));
- }
- }
- }
- else {
- if(iq2==0) {
- unsigned int ioff=q2->id()%2==0 ? 0 : 1;
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornRRLLWeights(2*ix+ioff,0));
- CEW [ix] = Complex(amp* EWRRLLWeights(2*ix+ioff,0));
- }
- }
- else {
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornRRRRWeights(ix,0));
- CEW [ix] = Complex(amp* EWRRRRWeights(ix,0));
- }
- }
- }
- // square
- for(unsigned int ix=0;ix<2;++ix) {
- for(unsigned int iy=0;iy<2;++iy) {
- bornME(ix,iy) += Cborn[ix]*conj(Cborn[iy]);
- EWME (ix,iy) += CEW [ix]*conj(CEW [iy]);
- }
- }
- }
- }
- // extra t-channel pieces if identical flavours
- if(ident) {
- for(unsigned int iq1=0;iq1<2;++iq1) {
- q1w.reset(iq1);
- q2w.reset(iq1);
- LorentzVector<complex<Energy> > current1 =
- q1w.dimensionedWave().vectorCurrent(q2w.dimensionedWave());
- q1barw.reset(iq1);
- q2barw.reset(iq1);
- LorentzVector<complex<Energy> > current2 =
- q2barw.dimensionedWave().vectorCurrent(q1barw.dimensionedWave());
- complex<Energy2> amp = current1.dot(current2);
- vector<Complex> Cborn(2),CEW(2);
- unsigned int ioff = q1->id()%2==0 ? 0 : 1;
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*borntChannelWeights(2*ix+ioff,0));
- CEW [ix] = Complex(amp*EWtChannelWeights(2*ix+ioff,0));
- }
- // square
- for(unsigned int ix=0;ix<2;++ix) {
- for(unsigned int iy=0;iy<2;++iy) {
- bornME(ix,iy) += Cborn[ix]*conj(Cborn[iy]);
- EWME (ix,iy) += CEW [ix]*conj(CEW [iy]);
- }
- }
- }
- }
- // colour factors
- double born = 2.*real(bornME(0,0))+9.*real(bornME(1,1));
- double EW = 2.*real( EWME(0,0))+9.*real( EWME(1,1));
- return EW/born;
-}
-
-double ElectroWeakReweighter::reweightqqbarqqbarT() const {
- // momenta and invariants
- Lorentz5Momentum p1 = subProcess()->incoming().first ->momentum();
- tcPDPtr q1 = subProcess()->incoming().first ->dataPtr();
- Lorentz5Momentum p2 = subProcess()->incoming().second->momentum();
- tcPDPtr q1bar = subProcess()->incoming().second->dataPtr();
- if(q1->id()<0) {
- swap(p1,p2 );
- swap(q1 ,q1bar);
- }
- Lorentz5Momentum p3 = subProcess()->outgoing()[0]->momentum();
- tcPDPtr q2bar = subProcess()->outgoing()[0]->dataPtr();
- Lorentz5Momentum p4 = subProcess()->outgoing()[1]->momentum();
- tcPDPtr q2 = subProcess()->outgoing()[1]->dataPtr();
- if(q2bar->id()>0) {
- swap(p3,p4 );
- swap(q2 ,q2bar);
- }
- Energy2 s = (p1+p2).m2();
- Energy2 t = (p1-p4).m2();
- Energy2 u = (p1-p3).m2();
- // boost to partonci rest frame
- Lorentz5Momentum psum=p1+p2;
- LorentzRotation boost(-psum.boostVector());
- p1 *= boost;
- p2 *= boost;
- p3 *= boost;
- p4 *= boost;
- p3.setMass(ZERO);
- p3.rescaleRho();
- p4.setMass(ZERO);
- p4.rescaleRho();
- assert(q1==q2 && q1bar==q2bar);
- assert( q1->id() != -q1bar->id() && q2->id() != -q2bar->id() );
- // LO and EW corrected matrix element coefficients
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- bornLLLLWeights,bornLLRRWeights,bornRRLLWeights,bornRRRRWeights,
- EWLLLLWeights,EWLLRRWeights,EWRRLLWeights,EWRRRRWeights;
- // LL
- if( q1->id() == ParticleID::b ||
- q1bar->id() == ParticleID::bbar ) {
- bornLLLLWeights = evaluateRunning(EWProcess::QtQtQQ,s,t,u,true ,1);
- EWLLLLWeights = evaluateRunning(EWProcess::QtQtQQ,s,t,u,false,1);
- }
- else {
- bornLLLLWeights = evaluateRunning(EWProcess::QQQQ,s,t,u,true ,1);
- EWLLLLWeights = evaluateRunning(EWProcess::QQQQ,s,t,u,false,1);
- }
- // RR -> LL
- if(q1->id()%2==0) {
- if(q1bar->id()==ParticleID::bbar) {
- bornRRLLWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,true ,1);
- EWRRLLWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,false,1);
- }
- else {
- bornRRLLWeights = evaluateRunning(EWProcess::QQUU,s,t,u,true ,1);
- EWRRLLWeights = evaluateRunning(EWProcess::QQUU,s,t,u,false,1);
- }
- }
- else {
- if(q1bar->id()==ParticleID::bbar) {
- bornRRLLWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,true ,1);
- EWRRLLWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,false,1);
- }
- else {
- bornRRLLWeights = evaluateRunning(EWProcess::QQDD,s,t,u,true ,1);
- EWRRLLWeights = evaluateRunning(EWProcess::QQDD,s,t,u,false,1);
- }
- }
- // LL -> RR
- if(abs(q1bar->id())%2==0) {
- if(q1->id()==ParticleID::b) {
- bornLLRRWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,true ,1);
- EWLLRRWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,false,1);
- }
- else {
- bornLLRRWeights = evaluateRunning(EWProcess::QQUU,s,t,u,true ,1);
- EWLLRRWeights = evaluateRunning(EWProcess::QQUU,s,t,u,false,1);
- }
- }
- else {
- if(q1->id()==ParticleID::b) {
- bornLLRRWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,true ,1);
- EWLLRRWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,false,1);
- }
- else {
- bornLLRRWeights = evaluateRunning(EWProcess::QQDD,s,t,u,true ,1);
- EWLLRRWeights = evaluateRunning(EWProcess::QQDD,s,t,u,false,1);
- }
- }
- // RR -> RR
- if(q1->id()%2==0) {
- if(abs(q1bar->id())%2==0) {
- bornRRRRWeights = evaluateRunning(EWProcess::UUUU,s,t,u,true ,1);
- EWRRRRWeights = evaluateRunning(EWProcess::UUUU,s,t,u,false,1);
- }
- else {
- bornRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,true ,1);
- EWRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,false,1);
- }
- }
- else {
- if(abs(q1bar->id())%2==0) {
- bornRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,true ,1);
- EWRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,false,1);
- }
- else {
- bornRRRRWeights = evaluateRunning(EWProcess::DDDD,s,t,u,true ,1);
- EWRRRRWeights = evaluateRunning(EWProcess::DDDD,s,t,u,false,1);
- }
- }
- // calculate the spinors
- SpinorWaveFunction q1w(p1,q1 ,incoming);
- SpinorBarWaveFunction q1barw(p2,q1bar,incoming);
- SpinorWaveFunction q2barw(p3,q2bar,outgoing);
- SpinorBarWaveFunction q2w(p4,q2 ,outgoing);
- boost::numeric::ublas::matrix<Complex>
- bornME = boost::numeric::ublas::zero_matrix<Complex>(2,2),
- EWME = boost::numeric::ublas::zero_matrix<Complex>(2,2);
- for(unsigned int iq1=0;iq1<2;++iq1) {
- q1w.reset(iq1);
- q2w.reset(iq1);
- LorentzVector<complex<Energy> > current1 =
- q1w.dimensionedWave().vectorCurrent(q2w.dimensionedWave());
- for(unsigned int iq2=0;iq2<2;++iq2) {
- q1barw.reset(iq2);
- q2barw.reset(iq2);
- LorentzVector<complex<Energy> > current2 =
- q2barw.dimensionedWave().vectorCurrent(q1barw.dimensionedWave());
- // calculate the amplitude
- complex<Energy2> amp = current1.dot(current2);
- vector<Complex> Cborn(2),CEW(2);
- if(iq1==0) {
- // LL RR
- if(iq2==0) {
- unsigned int ioff = q1->id()%2==0 ? 0 : 1;
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornLLRRWeights(2*ix+ioff,0));
- CEW [ix] = Complex(amp* EWLLRRWeights(2*ix+ioff,0));
- }
- }
- // LL LL
- else {
- unsigned int ioff;
- if(q1->id()%2==0) {
- ioff = abs(q1bar->id())%2==0 ? 0 : 2;
- }
- else {
- ioff = abs(q1bar->id())%2==0 ? 1 : 3;
- }
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornLLLLWeights(6*ix+ioff,0));
- CEW [ix] = Complex(amp* EWLLLLWeights(6*ix+ioff,0));
- }
- }
- }
- else {
- // RR RR
- if(iq2==0) {
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornRRRRWeights(ix,0));
- CEW [ix] = Complex(amp* EWRRRRWeights(ix,0));
- }
- }
- // RR LL
- else {
- unsigned int ioff=abs(q1bar->id())%2==0 ? 0 : 1;
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornRRLLWeights(2*ix+ioff,0));
- CEW [ix] = Complex(amp* EWRRLLWeights(2*ix+ioff,0));
- }
- }
- }
- // square
- for(unsigned int ix=0;ix<2;++ix) {
- for(unsigned int iy=0;iy<2;++iy) {
- bornME(ix,iy) += Cborn[ix]*conj(Cborn[iy]);
- EWME (ix,iy) += CEW [ix]*conj(CEW [iy]);
- }
- }
- }
- }
- // colour factors
- double born = 2.*real(bornME(0,0))+9.*real(bornME(1,1));
- double EW = 2.*real( EWME(0,0))+9.*real( EWME(1,1));
- return EW/born;
-}
-
-double ElectroWeakReweighter::reweightqqqq() const {
- // momenta and invariants
- Lorentz5Momentum p1 = subProcess()->incoming().first ->momentum();
- tcPDPtr q1 = subProcess()->incoming().first ->dataPtr();
- Lorentz5Momentum p2 = subProcess()->incoming().second->momentum();
- tcPDPtr q2 = subProcess()->incoming().second->dataPtr();
- Lorentz5Momentum p3 = subProcess()->outgoing()[0] ->momentum();
- tcPDPtr q3 = subProcess()->outgoing()[0] ->dataPtr();
- Lorentz5Momentum p4 = subProcess()->outgoing()[1] ->momentum();
- tcPDPtr q4 = subProcess()->outgoing()[1] ->dataPtr();
- if(q1->id()!=q3->id()) {
- swap(q3,q4);
- swap(p3,p4);
- }
- assert(q1->id()==q3->id());
- assert(q2->id()==q4->id());
- Energy2 s = (p1+p2).m2();
- Energy2 t = (p1-p4).m2();
- Energy2 u = (p1-p3).m2();
- // boost to partonci rest frame
- Lorentz5Momentum psum=p1+p2;
- LorentzRotation boost(-psum.boostVector());
- p1 *= boost;
- p2 *= boost;
- p3 *= boost;
- p4 *= boost;
- p3.setMass(ZERO);
- p3.rescaleRho();
- p4.setMass(ZERO);
- p4.rescaleRho();
- // LO and EW corrected matrix element coefficients
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- bornLLLLWeights,bornLLRRWeights,bornRRLLWeights,bornRRRRWeights,
- EWLLLLWeights,EWLLRRWeights,EWRRLLWeights,EWRRRRWeights;
- bool ident = q1->id()==q2->id();
- // LL -> LL
- if((q1->id()<=4&& q2->id()<=4)|| (q1->id()==5 && q2->id()==5)) {
- if(!ident) {
- bornLLLLWeights = evaluateRunning(EWProcess::QQQQ,s,t,u,true ,2);
- EWLLLLWeights = evaluateRunning(EWProcess::QQQQ,s,t,u,false,2);
- }
- else {
- bornLLLLWeights = evaluateRunning(EWProcess::QQQQiden,s,t,u,true ,2);
- EWLLLLWeights = evaluateRunning(EWProcess::QQQQiden,s,t,u,false,2);
- }
- }
- else if(q1->id()==5 || q2->id()==5) {
- bornLLLLWeights = evaluateRunning(EWProcess::QtQtQQ,s,t,u,true ,2);
- EWLLLLWeights = evaluateRunning(EWProcess::QtQtQQ,s,t,u,false,2);
- }
- else
- assert(false);
- // RR -> LL
- if(q1->id()%2==0) {
- if(q2->id()<5) {
- bornRRLLWeights = evaluateRunning(EWProcess::QQUU,s,t,u,true ,2);
- EWRRLLWeights = evaluateRunning(EWProcess::QQUU,s,t,u,false,2);
- }
- else {
- bornRRLLWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,true ,2);
- EWRRLLWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,false,2);
- }
- }
- else {
- if(q2->id()<5) {
- bornRRLLWeights = evaluateRunning(EWProcess::QQDD,s,t,u,true ,2);
- EWRRLLWeights = evaluateRunning(EWProcess::QQDD,s,t,u,false,2);
- }
- else {
- bornRRLLWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,true ,2);
- EWRRLLWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,false,2);
- }
- }
- // LL -> RR
- if(q1->id()<=4) {
- if(q2->id()%2!=0) {
- bornLLRRWeights = evaluateRunning(EWProcess::QQDD,s,t,u,true ,2);
- EWLLRRWeights = evaluateRunning(EWProcess::QQDD,s,t,u,false,2);
- }
- else {
- bornLLRRWeights = evaluateRunning(EWProcess::QQUU,s,t,u,true ,2);
- EWLLRRWeights = evaluateRunning(EWProcess::QQUU,s,t,u,false,2);
- }
- }
- else {
- if(q2->id()%2!=0) {
- bornLLRRWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,true ,2);
- EWLLRRWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,false,2);
- }
- else {
- bornLLRRWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,true ,2);
- EWLLRRWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,false,2);
- }
- }
- // RR -> RR
- if(q1->id()%2==0) {
- if(q2->id()%2==0) {
- if(ident) {
- bornRRRRWeights = evaluateRunning(EWProcess::UUUUiden,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::UUUUiden,s,t,u,false,2);
- }
- else {
- bornRRRRWeights = evaluateRunning(EWProcess::UUUU,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::UUUU,s,t,u,false,2);
- }
- }
- else {
- bornRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,false,2);
- }
- }
- else {
- if(q2->id()%2==0) {
- bornRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,false,2);
- }
- else {
- if(ident) {
- bornRRRRWeights = evaluateRunning(EWProcess::DDDDiden,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::DDDDiden,s,t,u,false,2);
- }
- else {
- bornRRRRWeights = evaluateRunning(EWProcess::DDDD,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::DDDD,s,t,u,false,2);
- }
- }
- }
- // extra terms for identical particles
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- borntChannelWeights,EWtChannelWeights;
- if(ident) {
- if(q1->id()%2==0) {
- borntChannelWeights = evaluateRunning(EWProcess::QQUU,s,u,t,true ,2);
- EWtChannelWeights = evaluateRunning(EWProcess::QQUU,s,u,t,false,2);
- }
- else if(q1->id()==5) {
- borntChannelWeights = evaluateRunning(EWProcess::QtQtDD,s,u,t,true ,2);
- EWtChannelWeights = evaluateRunning(EWProcess::QtQtDD,s,u,t,false,2);
- }
- else {
- borntChannelWeights = evaluateRunning(EWProcess::QQDD,s,u,t,true ,2);
- EWtChannelWeights = evaluateRunning(EWProcess::QQDD,s,u,t,false,2);
- }
- }
- SpinorWaveFunction q1w(p1,q1,incoming);
- SpinorWaveFunction q2w(p2,q2,incoming);
- SpinorBarWaveFunction q3w(p3,q3,outgoing);
- SpinorBarWaveFunction q4w(p4,q4,outgoing);
- boost::numeric::ublas::matrix<Complex>
- bornME = boost::numeric::ublas::zero_matrix<Complex>(2,2),
- EWME = boost::numeric::ublas::zero_matrix<Complex>(2,2);
- for(unsigned int iq1=0;iq1<2;++iq1) {
- q1w.reset(iq1);
- q3w.reset(iq1);
- LorentzVector<complex<Energy> > current1 =
- q1w.dimensionedWave().vectorCurrent(q3w.dimensionedWave());
- for(unsigned int iq2=0;iq2<2;++iq2) {
- q2w.reset(iq2);
- q4w.reset(iq2);
- LorentzVector<complex<Energy> > current2 =
- q2w.dimensionedWave().vectorCurrent(q4w.dimensionedWave());
- complex<Energy2> amp = current1.dot(current2);
- vector<Complex> Cborn(2),CEW(2);
- // amplitudes
- if(iq1==0) {
- // LL
- if(iq2==0) {
- unsigned int ioff;
- if(q1->id()%2==0) {
- ioff = q2->id()%2==0 ? 0 : 2;
- }
- else {
- ioff = q2->id()%2==0 ? 1 : 3;
- }
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornLLLLWeights(6*ix+ioff,0));
- CEW [ix] = Complex(amp*EWLLLLWeights(6*ix+ioff,0));
- }
- }
- // LR
- else {
- unsigned int ioff = q1->id()%2==0 ? 0 : 1;
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornLLRRWeights(2*ix+ioff,0));
- CEW [ix] = Complex(amp* EWLLRRWeights(2*ix+ioff,0));
- }
- }
- }
- else {
- if(iq2==0) {
- unsigned int ioff=q2->id()%2==0 ? 0 : 1;
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornRRLLWeights(2*ix+ioff,0));
- CEW [ix] = Complex(amp* EWRRLLWeights(2*ix+ioff,0));
- }
- }
- else {
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornRRRRWeights(ix,0));
- CEW [ix] = Complex(amp* EWRRRRWeights(ix,0));
- }
- }
- }
- // square
- for(unsigned int ix=0;ix<2;++ix) {
- for(unsigned int iy=0;iy<2;++iy) {
- bornME(ix,iy) += Cborn[ix]*conj(Cborn[iy]);
- EWME (ix,iy) += CEW [ix]*conj(CEW [iy]);
- }
- }
- }
- }
- // extra u-channel pieces if identical flavours
- if(ident) {
- for(unsigned int iq1=0;iq1<2;++iq1) {
- q1w.reset(iq1);
- q4w.reset(iq1);
- LorentzVector<complex<Energy> > current1 =
- q1w.dimensionedWave().vectorCurrent(q4w.dimensionedWave());
- if(iq1==0) {
- q2w.reset(1);
- q3w.reset(1);
- }
- else {
- q2w.reset(0);
- q3w.reset(0);
- }
- LorentzVector<complex<Energy> > current2 =
- q2w.dimensionedWave().vectorCurrent(q3w.dimensionedWave());
- complex<Energy2> amp = current1.dot(current2);
- vector<Complex> Cborn(2),CEW(2);
- unsigned int ioff = q1->id()%2==0 ? 0 : 1;
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*borntChannelWeights(2*ix+ioff,0));
- CEW [ix] = Complex(amp*EWtChannelWeights(2*ix+ioff,0));
- }
- // square
- for(unsigned int ix=0;ix<2;++ix) {
- for(unsigned int iy=0;iy<2;++iy) {
- bornME(ix,iy) += Cborn[ix]*conj(Cborn[iy]);
- EWME (ix,iy) += CEW [ix]*conj(CEW [iy]);
- }
- }
- }
- }
- // colour factors
- double born = 2.*real(bornME(0,0))+9.*real(bornME(1,1));
- double EW = 2.*real( EWME(0,0))+9.*real( EWME(1,1));
- return EW/born;
-}
-
-double ElectroWeakReweighter::reweightqbarqbarqbarqbar() const {
- // momenta and invariants
- Lorentz5Momentum p1 = subProcess()->incoming().first ->momentum();
- tcPDPtr qbar1 = subProcess()->incoming().first ->dataPtr();
- Lorentz5Momentum p2 = subProcess()->incoming().second->momentum();
- tcPDPtr qbar2 = subProcess()->incoming().second->dataPtr();
- Lorentz5Momentum p3 = subProcess()->outgoing()[0] ->momentum();
- tcPDPtr qbar3 = subProcess()->outgoing()[0] ->dataPtr();
- Lorentz5Momentum p4 = subProcess()->outgoing()[1] ->momentum();
- tcPDPtr qbar4 = subProcess()->outgoing()[1] ->dataPtr();
- if(qbar1->id()!=qbar3->id()) {
- swap(qbar3,qbar4);
- swap(p3,p4);
- }
- assert(qbar1->id()==qbar3->id());
- assert(qbar2->id()==qbar4->id());
- Energy2 s = (p1+p2).m2();
- Energy2 t = (p1-p4).m2();
- Energy2 u = (p1-p3).m2();
- // boost to partonic rest frame
- Lorentz5Momentum psum=p1+p2;
- LorentzRotation boost(-psum.boostVector());
- p1 *= boost;
- p2 *= boost;
- p3 *= boost;
- p4 *= boost;
- p3.setMass(ZERO);
- p3.rescaleRho();
- p4.setMass(ZERO);
- p4.rescaleRho();
- // LO and EW corrected matrix element coefficients
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- bornLLLLWeights,bornLLRRWeights,bornRRLLWeights,bornRRRRWeights,
- EWLLLLWeights,EWLLRRWeights,EWRRLLWeights,EWRRRRWeights;
- bool ident = qbar1->id()==qbar2->id();
- // LL -> LL
- if((abs(qbar1->id())<=4 && abs(qbar2->id())<=4) ||
- (abs(qbar1->id())==5 && abs(qbar2->id())==5)) {
- if(!ident) {
- bornLLLLWeights = evaluateRunning(EWProcess::QQQQ,s,t,u,true ,2);
- EWLLLLWeights = evaluateRunning(EWProcess::QQQQ,s,t,u,false,2);
- }
- else {
- bornLLLLWeights = evaluateRunning(EWProcess::QQQQiden,s,t,u,true ,2);
- EWLLLLWeights = evaluateRunning(EWProcess::QQQQiden,s,t,u,false,2);
- }
- }
- else if(abs(qbar1->id())==5 || abs(qbar2->id())==5) {
- bornLLLLWeights = evaluateRunning(EWProcess::QtQtQQ,s,t,u,true ,2);
- EWLLLLWeights = evaluateRunning(EWProcess::QtQtQQ,s,t,u,false,2);
- }
- else
- assert(false);
- // RR -> LL
- if(abs(qbar1->id())%2==0) {
- if(abs(qbar2->id())<5) {
- bornRRLLWeights = evaluateRunning(EWProcess::QQUU,s,t,u,true ,2);
- EWRRLLWeights = evaluateRunning(EWProcess::QQUU,s,t,u,false,2);
- }
- else {
- bornRRLLWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,true ,2);
- EWRRLLWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,false,2);
- }
- }
- else {
- if(abs(qbar2->id())<5) {
- bornRRLLWeights = evaluateRunning(EWProcess::QQDD,s,t,u,true ,2);
- EWRRLLWeights = evaluateRunning(EWProcess::QQDD,s,t,u,false,2);
- }
- else {
- bornRRLLWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,true ,2);
- EWRRLLWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,false,2);
- }
- }
- // LL -> RR
- if(abs(qbar1->id())<=4) {
- if(abs(qbar2->id())%2!=0) {
- bornLLRRWeights = evaluateRunning(EWProcess::QQDD,s,t,u,true ,2);
- EWLLRRWeights = evaluateRunning(EWProcess::QQDD,s,t,u,false,2);
- }
- else {
- bornLLRRWeights = evaluateRunning(EWProcess::QQUU,s,t,u,true ,2);
- EWLLRRWeights = evaluateRunning(EWProcess::QQUU,s,t,u,false,2);
- }
- }
- else {
- if(abs(qbar2->id())%2!=0) {
- bornLLRRWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,true ,2);
- EWLLRRWeights = evaluateRunning(EWProcess::QtQtDD,s,t,u,false,2);
- }
- else {
- bornLLRRWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,true ,2);
- EWLLRRWeights = evaluateRunning(EWProcess::QtQtUU,s,t,u,false,2);
- }
- }
- // RR -> RR
- if(abs(qbar1->id())%2==0) {
- if(abs(qbar2->id())%2==0) {
- if(ident) {
- bornRRRRWeights = evaluateRunning(EWProcess::UUUUiden,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::UUUUiden,s,t,u,false,2);
- }
- else {
- bornRRRRWeights = evaluateRunning(EWProcess::UUUU,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::UUUU,s,t,u,false,2);
- }
- }
- else {
- bornRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,false,2);
- }
- }
- else {
- if(abs(qbar2->id())%2==0) {
- bornRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::UUDD,s,t,u,false,2);
- }
- else {
- if(ident) {
- bornRRRRWeights = evaluateRunning(EWProcess::DDDDiden,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::DDDDiden,s,t,u,false,2);
- }
- else {
- bornRRRRWeights = evaluateRunning(EWProcess::DDDD,s,t,u,true ,2);
- EWRRRRWeights = evaluateRunning(EWProcess::DDDD,s,t,u,false,2);
- }
- }
- }
- // extra terms for identical particles
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- borntChannelWeights,EWtChannelWeights;
- if(ident) {
- if(abs(qbar1->id())%2==0) {
- borntChannelWeights = evaluateRunning(EWProcess::QQUU,s,u,t,true ,2);
- EWtChannelWeights = evaluateRunning(EWProcess::QQUU,s,u,t,false,2);
- }
- else if(abs(qbar1->id())==5) {
- borntChannelWeights = evaluateRunning(EWProcess::QtQtDD,s,u,t,true ,2);
- EWtChannelWeights = evaluateRunning(EWProcess::QtQtDD,s,u,t,false,2);
- }
- else {
- borntChannelWeights = evaluateRunning(EWProcess::QQDD,s,u,t,true ,2);
- EWtChannelWeights = evaluateRunning(EWProcess::QQDD,s,u,t,false,2);
- }
- }
- SpinorBarWaveFunction qbar1w(p1,qbar1,incoming);
- SpinorBarWaveFunction qbar2w(p2,qbar2,incoming);
- SpinorWaveFunction qbar3w(p3,qbar3,outgoing);
- SpinorWaveFunction qbar4w(p4,qbar4,outgoing);
- boost::numeric::ublas::matrix<Complex>
- bornME = boost::numeric::ublas::zero_matrix<Complex>(2,2),
- EWME = boost::numeric::ublas::zero_matrix<Complex>(2,2);
- for(unsigned int iq1=0;iq1<2;++iq1) {
- qbar1w.reset(iq1);
- qbar3w.reset(iq1);
- LorentzVector<complex<Energy> > current1 =
- qbar3w.dimensionedWave().vectorCurrent(qbar1w.dimensionedWave());
- for(unsigned int iq2=0;iq2<2;++iq2) {
- qbar2w.reset(iq2);
- qbar4w.reset(iq2);
- LorentzVector<complex<Energy> > current2 =
- qbar4w.dimensionedWave().vectorCurrent(qbar2w.dimensionedWave());
- complex<Energy2> amp = current1.dot(current2);
- vector<Complex> Cborn(2),CEW(2);
- // amplitudes
- if(iq1==1) {
- // LL
- if(iq2==1) {
- unsigned int ioff;
- if(abs(qbar1->id())%2==0) {
- ioff = abs(qbar2->id())%2==0 ? 0 : 2;
- }
- else {
- ioff = abs(qbar2->id())%2==0 ? 1 : 3;
- }
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornLLLLWeights(6*ix+ioff,0));
- CEW [ix] = Complex(amp* EWLLLLWeights(6*ix+ioff,0));
- }
- }
- // LR
- else {
- unsigned int ioff = abs(qbar1->id())%2==0 ? 0 : 1;
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornLLRRWeights(2*ix+ioff,0));
- CEW [ix] = Complex(amp* EWLLRRWeights(2*ix+ioff,0));
- }
- }
- }
- else {
- if(iq2==1) {
- unsigned int ioff=abs(qbar2->id())%2==0 ? 0 : 1;
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornRRLLWeights(2*ix+ioff,0));
- CEW [ix] = Complex(amp* EWRRLLWeights(2*ix+ioff,0));
- }
- }
- else {
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*bornRRRRWeights(ix,0));
- CEW [ix] = Complex(amp* EWRRRRWeights(ix,0));
- }
- }
- }
- // square
- for(unsigned int ix=0;ix<2;++ix) {
- for(unsigned int iy=0;iy<2;++iy) {
- bornME(ix,iy) += Cborn[ix]*conj(Cborn[iy]);
- EWME (ix,iy) += CEW [ix]*conj(CEW [iy]);
- }
- }
- }
- }
- // extra u-channel pieces if identical flavours
- if(ident) {
- for(unsigned int iq1=0;iq1<2;++iq1) {
- qbar1w.reset(iq1);
- qbar4w.reset(iq1);
- LorentzVector<complex<Energy> > current1 =
- qbar4w.dimensionedWave().vectorCurrent(qbar1w.dimensionedWave());
- if(iq1==0) {
- qbar2w.reset(1);
- qbar3w.reset(1);
- }
- else {
- qbar2w.reset(0);
- qbar3w.reset(0);
- }
- LorentzVector<complex<Energy> > current2 =
- qbar3w.dimensionedWave().vectorCurrent(qbar2w.dimensionedWave());
- complex<Energy2> amp = current1.dot(current2);
- vector<Complex> Cborn(2),CEW(2);
- unsigned int ioff = abs(qbar1->id())%2==0 ? 0 : 1;
- for(unsigned int ix=0;ix<2;++ix) {
- Cborn[ix] = Complex(amp*borntChannelWeights(2*ix+ioff,0));
- CEW [ix] = Complex(amp*EWtChannelWeights(2*ix+ioff,0));
- }
- // square
- for(unsigned int ix=0;ix<2;++ix) {
- for(unsigned int iy=0;iy<2;++iy) {
- bornME(ix,iy) += Cborn[ix]*conj(Cborn[iy]);
- EWME (ix,iy) += CEW [ix]*conj(CEW [iy]);
- }
- }
- }
- }
- // colour factors
- double born = 2.*real(bornME(0,0))+9.*real(bornME(1,1));
- double EW = 2.*real( EWME(0,0))+9.*real( EWME(1,1));
- return EW/born;
-}
diff --git a/MatrixElement/EW/ElectroWeakReweighter.h b/MatrixElement/EW/ElectroWeakReweighter.h
deleted file mode 100644
--- a/MatrixElement/EW/ElectroWeakReweighter.h
+++ /dev/null
@@ -1,212 +0,0 @@
-// -*- C++ -*-
-#ifndef Herwig_ElectroWeakReweighter_H
-#define Herwig_ElectroWeakReweighter_H
-//
-// This is the declaration of the ElectroWeakReweighter class.
-//
-
-#include "ThePEG/MatrixElement/ReweightBase.h"
-#include "EWCouplings.h"
-#include "CollinearSudakov.h"
-#include "SoftSudakov.h"
-
-namespace Herwig {
-
-using namespace ThePEG;
-
-/**
- * The ElectroWeakReweighter class.
- *
- * @see \ref ElectroWeakReweighterInterfaces "The interfaces"
- * defined for ElectroWeakReweighter.
- */
-class ElectroWeakReweighter: public ReweightBase {
-
-public:
-
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- ElectroWeakReweighter();
-
- /**
- * The destructor.
- */
- virtual ~ElectroWeakReweighter();
- //@}
-
-public:
-
- /**
- * Return the weight for the kinematical configuation provided by
- * the assigned XComb object (in the LastXCombInfo base class).
- */
- virtual double weight() const;
-
- /**
- *
- */
- static tEWCouplingsPtr coupling() {
- assert(staticEWCouplings_);
- return staticEWCouplings_;
- }
-
-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:
-
- /**
- * Functions to reweight specific processes
- */
- //@{
- /**
- * Reweight \f$g g\to q\bar{q}\f$
- */
- double reweightggqqbar() const;
-
- /**
- * Reweight \f$q\bar{q}\to g g\f$
- */
- double reweightqqbargg() const;
-
- /**
- * Reweight \f$q g\to qg\f$
- */
- double reweightqgqg() const;
-
- /**
- * Reweight \f$q g\to qg\f$
- */
- double reweightqbargqbarg() const;
-
- /**
- * Reweight \f$q\bar{q}\to q'\bar{q'}\f$ (s-channel)
- */
- double reweightqqbarqqbarS() const;
-
- /**
- * Reweight \f$q\bar{q}\to q'\bar{q'}\f$ (t-channel)
- */
- double reweightqqbarqqbarT() const;
-
- /**
- * Reweight \f$qq \to qq\f$
- */
- double reweightqqqq() const;
-
- /**
- * Reweight \f$\bar{q}\bar{q} \to \bar{q}\bar{q}\f$
- */
- double reweightqbarqbarqbarqbar() const;
- //@}
-
-protected:
-
- /**
- * Check the evolution for a fixed s,t,u
- */
- void testEvolution(Energy2 s,Energy2 t, Energy2 u) const;
-
- /**
- * Evalaute the running
- */
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- evaluateRunning(EWProcess::Process process, Energy2 s,
- Energy2 t, Energy2 u, bool born,
- unsigned int iswap) 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();
- //@}
-
-protected:
-
- /** @name Clone Methods. */
- //@{
- /**
- * Make a simple clone of this object.
- * @return a pointer to the new object.
- */
- virtual IBPtr clone() const;
-
- /** Make a clone of this object, possibly modifying the cloned object
- * to make it sane.
- * @return a pointer to the new object.
- */
- virtual IBPtr fullclone() const;
- //@}
-
-private:
-
- /**
- * The assignment operator is private and must never be called.
- * In fact, it should not even be implemented.
- */
- ElectroWeakReweighter & operator=(const ElectroWeakReweighter &) = delete;
-
-private:
-
- /**
- * The Electroweak Couplings
- */
- EWCouplingsPtr EWCouplings_;
-
- /**
- * The Collinear Sudakov
- */
- CollinearSudakovPtr collinearSudakov_;
-
- /**
- * The Soft Sudakov
- */
- SoftSudakovPtr softSudakov_;
-
- /**
- * The couplings to allow global access
- */
- static tEWCouplingsPtr staticEWCouplings_;
-
- /**
- * Whether or not to output testing information
- */
- bool testing_;
-
-};
-
-}
-
-#endif /* Herwig_ElectroWeakReweighter_H */
diff --git a/MatrixElement/EW/GroupInvariants.cc b/MatrixElement/EW/GroupInvariants.cc
deleted file mode 100644
--- a/MatrixElement/EW/GroupInvariants.cc
+++ /dev/null
@@ -1,268 +0,0 @@
-// -*- C++ -*-
-//
-// GroupInvariants.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
-//
-// Herwig is licenced under version 2 of the GPL, see COPYING for details.
-// Please respect the MCnet academic guidelines, see GUIDELINES for details.
-//
-//
-//
-#include "GroupInvariants.h"
-#include "ElectroWeakReweighter.h"
-
-using namespace Herwig;
-using namespace GroupInvariants;
-
-double GroupInvariants::K_Factor(unsigned int i,
- unsigned int N, bool high) {
- using Constants::pi;
- using Constants::zeta3;
- // Find K_i for SU(N) (or, for U(1) if N==1)
- // Relevent for finding the cusp anom. dim.
- if (N!=1 && N!=2 && N!=3) {
- std::cerr << "Error. In AnomDim, function K_Factor, N!={1,2,3}"
- << std::endl;
- assert(false);
- }
-
- double CA = C_A(N);
- double CF = C_F(N);
- double nF = n_F(N,high);
- double nS = n_S(N,high);
- double TF = T_F(N,high);
- double tS = t_S(N,high);
-
- if (i==1) {
- return (67.0/9.0-1.0/3.0*pi*pi)*CA - 20.0/9.0*nF*TF - 8.0/9.0*tS*nS;
- }
- else if (i==2) {
- return (245.0/6.0-134.0/27.0*pi*pi+22.0/3.0*zeta3+11.0/45.0*pi*pi*pi*pi)*CA*CA +
- (-418.0/27.0+40.0/27.0*pi*pi-56.0/3.0*zeta3)*CA*TF*nF +
- (-55.0/3.0+16.0*zeta3)*CF*TF*nF - 16.0/27.0*TF*TF*nF*nF;
- }
- else {
- std::cerr << "Error. In AnomDim, function K_Factor, i!={1,2}" << std::endl;
- assert(false);
- }
-}
-
-GaugeContributions GroupInvariants::cuspContributions(Energy mu, int K_ORDER,
- bool high) {
- using ThePEG::Constants::pi;
- if (K_ORDER > 3) {
- std::cerr << "Cusp anom dim. requested for K_ORDER>3.\n";
- assert(false);
- }
- // couplings (alphas) for U1, SU2, and SU3
- double a[3];
- if (high) {
- a[0] = ElectroWeakReweighter::coupling()->a1(mu)/(4.0*pi);
- a[1] = ElectroWeakReweighter::coupling()->a2(mu)/(4.0*pi);
- a[2] = ElectroWeakReweighter::coupling()->a3(mu)/(4.0*pi);
- }
- else {
- a[0] = ElectroWeakReweighter::coupling()->aEM(mu)/(4.0*pi);
- a[1] = 0.0;
- a[2] = ElectroWeakReweighter::coupling()->aS(mu)/(4.0*pi);
- }
-
- // gammaN[0] is really 4.0*C_F, but there is a factor of C_F included in the
- // G1-G3 matrices passed from HighRunning.h to the soft integrator.
- double gamma1[3];
- gamma1[0] = 4.0;
- gamma1[1] = K_Factor(1,1,high)*gamma1[0];
- gamma1[2] = K_Factor(2,1,high)*gamma1[0];
- double gamma2[3];
- gamma2[0] = 4.0;
- gamma2[1] = K_Factor(1,2,high)*gamma2[0];
- gamma2[2] = K_Factor(2,2,high)*gamma2[0];
- double gamma3[3];
- gamma3[0] = 4.0;
- gamma3[1] = K_Factor(1,3,high)*gamma3[0];
- gamma3[2] = K_Factor(2,3,high)*gamma3[0];
-
- GaugeContributions result;
- if (K_ORDER==0) {
- return result;
- }
- // LO bit
- if (K_ORDER>=1) {
- result.U1 += a[0]*gamma1[0];
- result.SU2 += a[1]*gamma2[0];
- result.SU3 += a[2]*gamma3[0];
- }
- // NLO bit
- if (K_ORDER>=2) {
- result.U1 += a[0]*a[0]*gamma1[1];
- result.SU2 += a[1]*a[1]*gamma2[1];
- result.SU3 += a[2]*a[2]*gamma3[1];
- }
- // NNLO bit
- if (K_ORDER>=3) {
- result.U1 += a[0]*a[0]*a[0]*gamma1[2];
- result.SU2 += a[1]*a[1]*a[1]*gamma2[2];
- result.SU3 += a[2]*a[2]*a[2]*gamma3[2];
- }
- return result;
-}
-
-double GroupInvariants::B_Factor(int i, int N, bool fermion,
- bool longitudinal) {
- using Constants::pi;
- using Constants::zeta3;
- // Find B_i for SU(N) (or, for U(1) if N==1)
- // Relevent for finding the collinear non-cusp anom. dim.
- if (N!=1 && N!=2 && N!=3) {
- std::cerr << "Error. In AnomDim, function B_Factor, N!={1,2,3}\n";
- assert(false);
- }
-
- double CA = C_A(N);
- double CF = C_F(N);
- double nF = n_F(N,true);
- double nS = n_S(N,true);
- double TF = T_F(N,true);
- double tS = t_S(N,true);
-
- if (longitudinal) {
- if (i==1) return -8.0*CF;
- // Two loop non-cusp not known for scalars
- else if (i==2) return 0.0;
- else assert(false);
- }
- else if (fermion) {
- if (i==1) return -6.0*CF;
- else if (i==2) {
- return (4.0*pi*pi - 48.0*zeta3 - 3.0)*CF*CF +
- (52.0*zeta3 - 11.0*pi*pi/3.0 - 961.0/27.0)*CA*CF +
- (4.0*pi*pi/3.0 + 260.0/27.0)*CF*TF*nF +
- (pi*pi/6.0 + 167.0/54.0)*CF*nS*tS*2.0;
- }
- else
- assert(false);
- }
- else {
- if (i==1) {
- return -2.0*( 11.0*CA/3.0 - 4.0*TF*nF/3.0 - nS*tS/3.0 );
- }
- else if (i==2) {
- return CA*CA*(11.0*pi*pi/9.0+4.0*zeta3-1384.0/27.0) +
- 2.0*CA*nF*TF*(256.0/27.0-2.0*pi*pi/9.0) + 8.0*CF*nF*TF;
- }
- else assert(false);
- }
-}
-
-double GroupInvariants::B_Factor_Low(int i, int N, bool fermion,
- double boostFactor) {
- using Constants::pi;
- using Constants::zeta3;
- // Find B_i for SU(N) (or, for U(1) if N==1)
- // Relevent for finding the collinear non-cusp anom. dim.
- if (N!=1 && N!=2 && N!=3) {
- std::cerr << "Error. In AnomDim, function B_Factor, N!={1,2,3}\n";
- assert(false);
- }
-
- double CA = C_A(N);
- double CF = C_F(N);
- double nF = n_F(N,false);
- double nS = n_S(N,false);
- double TF = T_F(N,false);
- double tS = t_S(N,false);
-
- if (abs(boostFactor)>0.001) {
- if (i==1) return -4.0*CF;
- // Two loop non-cusp not known for bHQET top, W_L, and W_T fields.
- else if (i==2) return 0.0;
- else assert(false);
- }
- else if (fermion) {
- if (i==1) return -6.0*CF;
- else if (i==2) {
- return (4.0*pi*pi - 48.0*zeta3 - 3.0)*CF*CF +
- (52.0*zeta3 - 11.0*pi*pi/3.0 - 961.0/27.0)*CA*CF +
- (4.0*pi*pi/3.0 + 260.0/27.0)*CF*TF*nF +
- (pi*pi/6.0 + 167.0/54.0)*CF*nS*tS*2.0;
- }
- else
- assert(false);
- }
- // Gluon and Photon are the only things left... use Gauge Boson NonCusps:
- else {
- if (i==1) return -2.0*( 11.0*CA/3.0 - 4.0*TF*nF/3.0 - nS*tS/3.0 );
- else if (i==2) {
- return CA*CA*(11.0*pi*pi/9.0+4.0*zeta3-1384.0/27.0) +
- 2.0*CA*nF*TF*(256.0/27.0-2.0*pi*pi/9.0) + 8.0*CF*nF*TF;
- }
- else
- assert(false);
- }
-}
-
-GaugeContributions GroupInvariants::BContributions(Energy mu,
- int B_ORDER,
- bool fermion,
- bool longitudinal) {
- using Constants::pi;
- // NOTE! THIS RETURNS 2*Gamma+sigma, AND SHOULD BE MULTIPLIED BY 1/2 IN
- // THE COLLINEAR ANOMALOUS DIMENSION INTEGRAND
- if (B_ORDER>2) {
- std::cerr << "Non-cusp collinear anom dim. requested for B_ORDER>2.\n";
- assert(false);
- }
-
- double a[3]; // alpha/(4pi) for U1, SU2, and SU3
-
- a[0] = ElectroWeakReweighter::coupling()->a1(mu)/(4.0*pi);
- a[1] = ElectroWeakReweighter::coupling()->a2(mu)/(4.0*pi);
- a[2] = ElectroWeakReweighter::coupling()->a3(mu)/(4.0*pi);
-
- GaugeContributions result;
- if (B_ORDER==0) {
- return result;
- }
- if (B_ORDER>=1) {
- result.SU3 += a[2]*B_Factor(1,3,fermion,longitudinal);
- result.SU2 += a[1]*B_Factor(1,2,fermion,longitudinal);
- result.U1 += a[0]*B_Factor(1,1,fermion,longitudinal);
- }
- if (B_ORDER>=2) {
- result.SU3 += a[2]*a[2]*B_Factor(2,3,fermion,longitudinal);
- result.SU2 += a[1]*a[1]*B_Factor(2,2,fermion,longitudinal);
- result.U1 += a[0]*a[0]*B_Factor(2,1,fermion,longitudinal);
- }
- return result;
-}
-
-GaugeContributions GroupInvariants::BContributionsLow(Energy mu,
- int B_ORDER,
- bool fermion,
- double boostFactor) {
- using Constants::pi;
- // NOTE! THIS RETURNS 2*Gamma+sigma, AND SHOULD BE MULTIPLIED BY 1/2 IN
- // THE COLLINEAR ANOMALOUS DIMENSION INTEGRAND
- if (B_ORDER>2) {
- std::cerr << "Non-cusp collinear anom dim. requested for B_ORDER>2.\n";
- }
- // alpha/(4pi) for U1, SU2, and SU3
- double a[3];
- a[0] = ElectroWeakReweighter::coupling()->aEM(mu)/(4.0*pi);
- a[1] = 0.0;
- a[2] = ElectroWeakReweighter::coupling()->aS(mu)/(4.0*pi);
- GaugeContributions result;
- if (B_ORDER==0) {
- return result;
- }
- if (B_ORDER>=1) {
- result.SU3 += a[2]*B_Factor_Low(1,3,fermion,boostFactor);
- result.SU2 += a[1]*B_Factor_Low(1,2,fermion,boostFactor);
- result.U1 += a[0]*B_Factor_Low(1,1,fermion,boostFactor);
- }
- if (B_ORDER>=2) {
- result.SU3 += a[2]*a[2]*B_Factor_Low(2,3,fermion,boostFactor);
- result.SU2 += a[1]*a[1]*B_Factor_Low(2,2,fermion,boostFactor);
- result.U1 += a[0]*a[0]*B_Factor_Low(2,1,fermion,boostFactor);
- }
- return result;
-}
diff --git a/MatrixElement/EW/GroupInvariants.h b/MatrixElement/EW/GroupInvariants.h
deleted file mode 100644
--- a/MatrixElement/EW/GroupInvariants.h
+++ /dev/null
@@ -1,500 +0,0 @@
-// -*- C++ -*-
-//
-// GroupInvariants.h is a part of Herwig - A multi-purpose Monte Carlo event generator
-//
-// 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_GroupInvariants_H
-#define HERWIG_GroupInvariants_H
-#include "ThePEG/Config/ThePEG.h"
-#include "ThePEG/Config/Unitsystem.h"
-#include <cassert>
-// work around a Boost 1.64 bug where ublas headers would fail otherwise
-#include <boost/version.hpp>
-#if (BOOST_VERSION / 100 >= 1064)
-#include <boost/serialization/array_wrapper.hpp>
-#endif
-#include <boost/numeric/ublas/matrix.hpp>
-
-namespace Herwig {
-using namespace ThePEG;
-
-namespace GroupInvariants {
-
- /**
- * Simple struct for storing the different gauge contributions
- */
- struct GaugeContributions {
-
- /**
- * Default Constructor
- */
- GaugeContributions(double inSU3=0.,
- double inSU2=0., double inU1=0.)
- : SU3(inSU3),SU2(inSU2),U1(inU1)
- {}
- /**
- * \f$SU(3)\f$
- */
- double SU3;
-
- /**
- * \f$SU(2)\f$
- */
- double SU2;
-
- /**
- * \f$U(1)\f$
- */
- double U1;
- };
-
-
- /**
- * The \f$SU(N)\f$ \f$C_A\f$
- */
- inline double C_A(unsigned int N) {
- return N !=1 ? double(N) : 0.;
- }
-
- /**
- * The \f$SU(N)\f$ \f$C_F\f$
- */
- inline double C_F(unsigned int N) {
- return N !=1 ? 0.5*(double(N*N)-1.)/double(N) : 1.;
- }
-
- /*
- * The \f$SU(N)\f$ \f$C_d\f$
- */
- inline double C_d(unsigned int N) {
- return (double(N*N)-4.)/double(N);
- }
-
- /**
- * The \f$SU(N)\f$\f$C_1\f$
- */
- inline double C_1(unsigned int N) {
- double N2(N*N);
- return 0.25*(N2-1.0)/N2;
- }
-
- /**
- * \f$T_F\f$
- */
- inline double T_F(unsigned int N, bool high) {
- if(high) {
- return N !=1 ? 0.5 : 5.0/3.0;
- }
- else {
- return N !=1 ? 0.5 : 20.0/3.0;
- }
- }
-
- /**
- * \f$t_S\f$
- */
- inline double t_S(unsigned int, bool ) {
- return 0.5;
- }
-
- /**
- * / Number of complex scalars in the fundamental rep. of SU(N)/U(1)
- */
- inline double n_S(unsigned int N, bool high) {
- if(high) {
- if(N==2 || N==1) return 1.0;
- else if(N==3) return 0.0;
- else assert(false);
- }
- else {
- if(N>=1&&N<=3) return 0.;
- else assert(false);
- }
- }
-
- /**
- * Number of Dirac Fermions in the fund. rep. of SU(N) (or U(1) for N==1)
- */
- inline double n_F(unsigned int N, bool high) {
- if(high) {
- if(N==1) return 3.0;
- else if(N==2 || N==3) return 6.0;
- else assert(false);
- }
- else {
- if(N==1) return 1.0;
- else if(N==2) return 0.0;
- else if(N==3) return 5.0;
- else assert(false);
- }
- }
-
- /**
- * Find K_i for gauge group N. high=false for running at mu<mZ
- */
- double K_Factor(unsigned int i,unsigned int N, bool high);
-
- /**
- * Find B_i for gauge group N, high energy
- */
- double B_Factor(int i, int N, bool fermion, bool longitudinal);
-
- /**
- * Find B_i for gauge group N, low energy
- */
- double B_Factor_Low(int i, int N, bool fermion, double boostFactor);
-
- /**
- * Contributions to the Cusps
- */
- GaugeContributions cuspContributions(Energy mu, int K_ORDER, bool high);
-
- /**
- * Contributions to B, high energy
- */
- GaugeContributions BContributions(Energy mu, int B_ORDER,
- bool fermion, bool longitudinal);
-
- /**
- * Contributions to B, low energy
- */
- GaugeContributions BContributionsLow(Energy mu, int B_ORDER,
- bool fermion, double boostFactor);
-
- inline Complex PlusLog(double arg) {
- static const Complex I(0,1.0);
- if (arg>0.0)
- return log(arg);
- else if (arg<0.0)
- return log(-arg)+I*Constants::pi;
- else
- assert(false);
- }
-
- inline Complex MinusLog(double arg) {
- static const Complex I(0,1.0);
- if (arg>0.0)
- return log(arg);
- else if (arg<0.0)
- return log(-arg)-I*Constants::pi;
- else
- assert(false);
- }
-
- inline Complex getT(Energy2 s, Energy2 t) {
- return MinusLog(-t/GeV2) - MinusLog(-s/GeV2);
- }
-
- inline Complex getU(Energy2 s, Energy2 u) {
- return MinusLog(-u/GeV2) - MinusLog(-s/GeV2);
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma2(Complex U, Complex T) {
- boost::numeric::ublas::matrix<Complex> output(2,2);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,0) = (-3.0/2.0)*I*pi + (T+U);
- output(1,1) = (-3.0/2.0)*I*pi;
- output(0,1) = 2.0*(T-U);
- output(1,0) = (3.0/8.0)*(T-U);
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma2ST(Complex U, Complex T) {
- boost::numeric::ublas::matrix<Complex> output(2,2);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,0) = 3./2.*(T-I*pi) + U -2.*T;
- output(1,1) = 3./2.*(T-I*pi);
- output(0,1) = -2.0*U;
- output(1,0) = -(3.0/8.0)*U;
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma2SU(Complex U, Complex T) {
- boost::numeric::ublas::matrix<Complex> output(2,2);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,0) = 3./2.*(U-I*pi) + T - 2.*U;
- output(1,1) = 3./2.*(U-I*pi);
- output(0,1) = 2.0*T;
- output(1,0) = (3.0/8.0)*T;
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma2w(Complex U, Complex T) {
- boost::numeric::ublas::matrix<Complex> output = boost::numeric::ublas::zero_matrix<Complex>(5,5);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,0) += -I*pi*11.0/4.0;
- output(0,1) += U-T;
- output(1,0) += 2.0*(U-T);
- output(1,1) += -I*pi*11.0/4.0 + (T+U);
- output(2,2) += -7.0/4.0*I*pi + (U+T);
- output(3,3) += -7.0/4.0*I*pi + (U+T);
- output(4,4) += -3.0/4.0*I*pi;
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma2Singlet() {
- using namespace boost::numeric::ublas;
- matrix<Complex> output = zero_matrix<Complex>(2,2);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,0) = output(1,1) = -0.75*I*pi;
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma2SingletST(Complex T) {
- using namespace boost::numeric::ublas;
- matrix<Complex> output = zero_matrix<Complex>(2,2);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,0) = output(1,1) = 0.75*(T-I*pi);
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma2SingletSU(Complex U) {
- using namespace boost::numeric::ublas;
- matrix<Complex> output = zero_matrix<Complex>(2,2);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,0) = output(1,1) = 0.75*(U-I*pi);
- return output;
- }
-
- inline Complex Gamma1(double hypercharge) {
- Complex I(0,1.0);
- return -I*Constants::pi*sqr(hypercharge);
- }
-
- inline Complex Gamma1ST(double hypercharge,Complex T) {
- Complex I(0,1.0);
- return (T-I*Constants::pi)*sqr(hypercharge);
- }
-
- inline Complex Gamma1SU(double hypercharge,Complex U) {
- Complex I(0,1.0);
- return (U-I*Constants::pi)*sqr(hypercharge);
- }
-
- inline Complex Gamma1(double y1, double y2, Complex T, Complex U) {
- Complex I(0,1.0);
- return -I*Constants::pi*(y1*y1+y2*y2) + 2.0*y1*y2*(T-U);
- }
-
- inline Complex Gamma1ST(double y1, double y2, Complex T, Complex U) {
- Complex I(0,1.0);
- return (T-I*Constants::pi)*(y1*y1+y2*y2) - 2.0*y1*y2*U;
- }
-
- inline Complex Gamma1SU(double y1, double y2, Complex T, Complex U) {
- Complex I(0,1.0);
- return (U-I*Constants::pi)*(y1*y1+y2*y2) + 2.0*y1*y2*T;
- }
-
- inline Complex Gamma1(double y1, double y2, double y3, double y4,
- Complex T, Complex U) {
- Complex I(0,1.0);
- return -I*Constants::pi*(y1*y1+y2*y2+y3*y3+y4*y4)/2.0 +
- (y1*y4+y2*y3)*T - (y1*y3+y2*y4)*U;
- }
-
- inline Complex Gamma1ST(double y1, double y2, double y3, double y4,
- Complex T, Complex U) {
- Complex I(0,1.0);
- return (T-I*Constants::pi)*(y1*y1+y2*y2+y3*y3+y4*y4)/2.0 -
- (y1*y4+y2*y3)*T - (y1*y3+y2*y4)*(U-T);
- }
-
- inline Complex Gamma1SU(double y1, double y2, double y3, double y4,
- Complex T, Complex U) {
- Complex I(0,1.0);
- return (U-I*Constants::pi)*(y1*y1+y2*y2+y3*y3+y4*y4)/2.0 +
- (y1*y4+y2*y3)*(T-U) + (y1*y3+y2*y4)*U;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma3(Complex U, Complex T) {
- boost::numeric::ublas::matrix<Complex> output = boost::numeric::ublas::zero_matrix<Complex>(2,2);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,0) = -(8.0/3.0)*I*pi;
- output(1,1) = -(8.0/3.0)*I*pi;
- output(0,0) += (7.0/3.0)*T + (2.0/3.0)*U;
- output(0,1) = 2.0*(T-U);
- output(1,0) = (4.0/9.0)*(T-U);
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma3ST(Complex U, Complex T) {
- boost::numeric::ublas::matrix<Complex> output = boost::numeric::ublas::zero_matrix<Complex>(2,2);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,0) = 8./3.*(T-I*pi);
- output(1,1) = 8./3.*(T-I*pi);
- output(0,0) += -3.*T + 2./3.*U;
- output(0,1) = -2.*U;
- output(1,0) = -4./9.*U;
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma3SU(Complex U, Complex T) {
- boost::numeric::ublas::matrix<Complex> output = boost::numeric::ublas::zero_matrix<Complex>(2,2);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,0) = 8./3.*(U-I*pi);
- output(1,1) = 8./3.*(U-I*pi);
- output(0,0) += 7./3.*T -3.*U;
- output(0,1) = 2.*T;
- output(1,0) = 4./9.*T;
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma3g(Complex U, Complex T) {
- boost::numeric::ublas::matrix<Complex> output = boost::numeric::ublas::zero_matrix<Complex>(3,3);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,2) = U-T;
- output(1,1) = 3.0/2.0*(T+U);
- output(1,2) = 3.0/2.0*(U-T);
- output(2,0) = 2.0*(U-T);
- output(2,1) = 5.0/6.0*(U-T);
- output(2,2) = 3.0/2.0*(T+U);
- for (unsigned int i=0; i<3; i++) {
- output(i,i) += -13.0/3.0*I*pi;
- }
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma3gST(Complex U, Complex T) {
- boost::numeric::ublas::matrix<Complex> output = boost::numeric::ublas::zero_matrix<Complex>(3,3);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,2) = U;
- output(1,1) = 3.0/2.0*(U-2.*T);
- output(1,2) = 3.0/2.0*U;
- output(2,0) = 2.0*U;
- output(2,1) = 5.0/6.0*U;
- output(2,2) = 3.0/2.0*(U-2.*T);
- for (unsigned int i=0; i<3; i++) {
- output(i,i) += 13.0/3.0*(T-I*pi);
- }
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma3gSU(Complex U, Complex T) {
- boost::numeric::ublas::matrix<Complex> output = boost::numeric::ublas::zero_matrix<Complex>(3,3);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,2) = -T;
- output(1,1) = 3./2.*(T-2.*U);
- output(1,2) = -3./2.*T;
- output(2,0) = -2.0*T;
- output(2,1) =-5./6.*T;
- output(2,2) = 3./2.*(T-2.*U);
- for (unsigned int i=0; i<3; i++) {
- output(i,i) += 13./3.*(U-I*pi);
- }
- return output;
- }
-
- inline boost::numeric::ublas::matrix<Complex> Gamma3Singlet() {
- boost::numeric::ublas::matrix<Complex> output = boost::numeric::ublas::zero_matrix<Complex>(2,2);
- static const Complex I(0,1.0);
- using Constants::pi;
- output(0,0) = output(1,1) = -4.0/3.0*I*pi;
- return output;
- }
-
- /**
- * Number of fermion generations (only used in gauge boson HighCMatching)
- */
- inline double n_g() { return 3.0; }
-
- /**
- * Number of complex scalars in the fundamental rep. of SU(N)
- */
- inline double nSWeyl(unsigned int N, bool high) {
- if(high) {
- if(N==2 || N==1) return 1.0;
- else if (N==3) return 0.0;
- else assert(false);
- }
- else {
- if( N==1 || N==3 ) return 0.0;
- else assert(false);
- }
- }
-
- /**
- * Number of Weyl Fermions in the fundamental rep. of SU(N)
- */
- inline double nFWeyl(unsigned int N, bool high) {
- if(high) {
- if(N==2 || N==3) return 12.0;
- else assert(false);
- }
- else {
- if(N==3) return 10.0;
- else if(N==1) return 2.0;
- else assert(false);
- }
- }
-
- inline double TFWeyl(unsigned int) {
- return 0.5;
- }
-
- inline double tSWeyl(unsigned int) {
- return 0.5;
- }
-
- inline Complex WFunction(Energy mu, Energy2 s) {
- using Constants::pi;
- assert(abs(s)>ZERO);
- Complex ln = MinusLog(-s/(mu*mu));
- return (-1.0*ln*ln + 3.0*ln+pi*pi/6.0-8.0);
- }
-
- /**
- * \fX_N\f% function, v is either t or u
- */
- inline Complex XNFunction(unsigned int N, Energy mu, Energy2 s, Energy2 v) {
- using Constants::pi;
- assert(abs(s)>ZERO);
- Complex ls = MinusLog(-s/(mu*mu));
- return (2.0*C_F(N)*WFunction(mu,s) +
- C_A(N)*(2.0*ls*ls - 2.0*MinusLog((s+v)/(mu*mu))*ls -
- 11.0/3.0*ls + pi*pi + 85.0/9.0) +
- (2.0/3.0*ls - 10.0/9.0) * TFWeyl(N) * nFWeyl(N,true) +
- (1.0/3.0*ls - 8.0/9.0) * TFWeyl(N) * nSWeyl(N,true));
- }
-
- /**
- * \f$\Pi_1\f$ function
- */
- inline Complex PI1_function(Energy mu, Energy2 s) {
- assert(abs(s)>ZERO);
- return ((41.0/6.0)*MinusLog(-s/(mu*mu))-104.0/9.0);
- }
-
- /**
- * \f$\tilde{f}\f$ function, v is either t or u
- */
- inline Complex fTildeFunction(Energy mu, Energy2 s, Energy2 v) {
- using Constants::pi;
- assert(abs(s)>ZERO);
- Complex ls = MinusLog(-s/GeV2), lv = MinusLog(-v/GeV2);
- Complex lsv = MinusLog((s+v)/GeV2);
- return (-2.0*double(s/(s+v))*(lv-ls) +
- double(s*(s+2.0*v)/((s+v)*(s+v))) * ((lv-ls)*(lv-ls) + pi*pi) +
- 4.0*MinusLog(-s/(mu*mu))*(lv-lsv));
- }
-}
-}
-
-#endif // HERWIG_GroupInvariants_H
diff --git a/MatrixElement/EW/HighEnergyMatching.cc b/MatrixElement/EW/HighEnergyMatching.cc
deleted file mode 100644
--- a/MatrixElement/EW/HighEnergyMatching.cc
+++ /dev/null
@@ -1,1181 +0,0 @@
-// -*- C++ -*-
-//
-// HighEnergyMatching.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
-//
-// Herwig is licenced under version 2 of the GPL, see COPYING for details.
-// Please respect the MCnet academic guidelines, see GUIDELINES for details.
-//
-//
-//
-#include "HighEnergyMatching.h"
-#include "ElectroWeakReweighter.h"
-#include "GroupInvariants.h"
-#include <boost/numeric/ublas/operation.hpp>
-#include <boost/numeric/ublas/vector.hpp>
-
-using namespace Herwig;
-using namespace HighEnergyMatching;
-using namespace GroupInvariants;
-using namespace EWProcess;
-
-namespace {
-
-/**
- * \f$M_N\f$, this matrix is used for identical particle scattering
- */
-boost::numeric::ublas::matrix<Complex> M_N(unsigned int suN) {
- double N(suN);
- boost::numeric::ublas::matrix<Complex> M(2,2);
- M(0,0) = -1.0/N;
- M(0,1) = 2.0;
- M(1,0) = 0.5 - 1.0/(2.0*N*N);
- M(1,1) = 1.0/N;
- return M;
-}
-
-// #ifdef ThePEG_HAS_UNITS_CHECKING
-void axpy_prod_local(const boost::numeric::ublas::matrix<Complex> & A,
- const boost::numeric::ublas::matrix<complex<InvEnergy2> > & B,
- boost::numeric::ublas::matrix<complex<InvEnergy2> > & C) {
- assert(A.size2()==B.size1());
- C.resize(A.size1(),B.size2());
- for(unsigned int ix=0;ix<A.size1();++ix) {
- for(unsigned int iy=0;iy<B.size2();++iy) {
- C(ix,iy) = ZERO;
- for(unsigned int iz=0;iz<A.size2();++iz) {
- C(ix,iy) += A(ix,iz)*B(iz,iy);
- }
- }
- }
-}
-
-void axpy_prod_local(const boost::numeric::ublas::matrix<complex<InvEnergy2> > & A,
- const boost::numeric::ublas::matrix<Complex> & B,
- boost::numeric::ublas::matrix<complex<InvEnergy2> > & C) {
- assert(A.size2()==B.size1());
- C.resize(A.size1(),B.size2());
- for(unsigned int ix=0;ix<A.size1();++ix) {
- for(unsigned int iy=0;iy<B.size2();++iy) {
- C(ix,iy) = ZERO;
- for(unsigned int iz=0;iz<A.size2();++iz) {
- C(ix,iy) += A(ix,iz)*B(iz,iy);
- }
- }
- }
-}
-// #else
-// void axpy_prod_local(const boost::numeric::ublas::matrix<Complex> & A,
-// const boost::numeric::ublas::matrix<Complex> & B,
-// boost::numeric::ublas::matrix<Complex> & C) {
-// assert(A.size2()==B.size1());
-// C.resize(A.size1(),B.size2());
-// axpy_prod(A,B,C);
-// }
-// #endif
-
-}
-
-boost::numeric::ublas::matrix<complex<InvEnergy2> >
-HighEnergyMatching::highEnergyMatching(Energy highScale,
- Energy2 s, Energy2 t, Energy2 u,
- EWProcess::Process process,
- bool oneLoop, bool includeAlphaS2) {
- switch (process) {
- case QQQQ: case QQQQiden:
- case QtQtQQ: case QQUU:
- case QtQtUU: case QQtRtR:
- case QQDD: case QtQtDD:
- case QQLL: case QQEE:
- case UUUU: case UUUUiden:
- case tRtRUU: case UUDD:
- case tRtRDD: case UULL:
- case UUEE: case DDDD:
- case DDDDiden: case DDLL:
- case DDEE: case LLLL:
- case LLLLiden: case LLEE:
- case EEEE: case EEEEiden:
- return SpinHalfMatching(highScale,s,t,u,process,oneLoop,includeAlphaS2);
- break;
- case QQWW:
- case QQWG:
- case QQBG:
- case QQGG:
- case QtQtGG:
- case LLWW:
- case UUBB:
- case UUBG:
- case UUGG:
- case tRtRGG:
- case DDBB:
- case DDBG:
- case DDGG:
- case EEBB:
- return Spin1HighMatching(highScale,s,t,u,process,oneLoop,includeAlphaS2);
- break;
- case QQPhiPhi:
- case LLPhiPhi:
- case UUPhiPhi:
- case DDPhiPhi:
- case EEPhiPhi:
- return Spin0HighMatching(highScale,s,t,u,process,oneLoop,includeAlphaS2);
- break;
- default:
- assert(false);
- break;
- }
-}
-
-boost::numeric::ublas::matrix<complex<InvEnergy2> >
-HighEnergyMatching::SpinHalfMatching(Energy highScale,
- Energy2 s, Energy2 t, Energy2 u,
- EWProcess::Process process,
- bool oneLoop, bool includeAlphaS2) {
- using Constants::pi;
- boost::numeric::ublas::matrix<complex<InvEnergy2> > highC;
- Energy Q = highScale;
- double a1 = ElectroWeakReweighter::coupling()->a1(Q);
- double a2 = ElectroWeakReweighter::coupling()->a2(Q);
- double a3 = ElectroWeakReweighter::coupling()->a3(Q);
- double y_t = ElectroWeakReweighter::coupling()->y_t(Q);
- unsigned int order = !oneLoop ? 0 : 1;
- double Yi(0.),Yf(0.);
-
- Complex Ls = MinusLog(-s/(Q*Q));
-
- double C_A_2 = C_A(2);
- double C_A_3 = C_A(3);
- double C_F_2 = C_F(2);
- double C_F_3 = C_F(3);
- double C_d_2 = C_d(2);
- double C_d_3 = C_d(3);
- double C_1_2 = C_1(2);
- double C_1_3 = C_1(3);
- Complex W = WFunction(Q,s);
- Complex X_2_st = XNFunction(2,Q,s,t);
- //Complex X_2_su = XNFunction(2,Q,s,u);
- Complex X_3_st = XNFunction(3,Q,s,t);
- Complex X_3_su = XNFunction(3,Q,s,u);
- Complex PI1 = PI1_function(Q,s);
- Complex fTilde_st = fTildeFunction(Q,s,t);
- Complex fTilde_su = fTildeFunction(Q,s,u);
-
- switch (process) {
-
- case QQQQ:
- // NOTE this 4x1 column vector highC is given by (C_11,C_21,C_12,C_22),
- // where C_12 is the coeff. for the term that transforms under SU(2) but not SU(3)
- Yi = Yf = 1./6.;
- highC.resize(4,1);
- highC(0,0) = ZERO;
- highC(2,0) = 4.0*pi*a2 / s;
- highC(1,0) = 4.0*pi*a3 / s;
- highC(3,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(-2.0*a2*a3*fTilde_st);
- highC(2,0) += (1.0/s)*(a2*a2*(X_2_st-(C_d_2+C_A_2)/4.0*fTilde_st) +
- 2.0*(a1*a2*Yi*Yf+a2*a3*C_F_3)*W -
- 2.0*a1*a2*Yi*Yf*fTilde_st);
- highC(1,0) += (1.0/s)*(2.0*(a1*a3*Yi*Yf+a2*a3*C_F_2)*W -
- 2.0*a1*a3*Yi*Yf*fTilde_st);
- highC(3,0) += (1.0/s)*(-1.0*(a2*a2*C_1_2+a1*a1*Yi*Yi*Yf*Yf)*fTilde_st +
- a1*a1*Yi*Yf*PI1 +
- 2.0*(a1*a3*Yi*Yf*C_F_3+a1*a2*Yi*Yf*C_F_2+a1*a1*Yi*Yi*Yf*Yf)*W);
- if (includeAlphaS2) {
- highC(1,0) += (1.0/s)*(a3*a3*(X_3_st-(C_d_3+C_A_3)/4.0*fTilde_st));
-
- highC(3,0) += (1.0/s)*(-1.0*(a3*a3*C_1_3)*fTilde_st);
- }
- }
- break;
-
- case QQQQiden:
- {
- Process parentCase = QQQQ;
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highCs_st = highEnergyMatching(Q,s,t,u,parentCase,oneLoop,includeAlphaS2);
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highCs_ts = highEnergyMatching(Q,t,s,u,parentCase,oneLoop,includeAlphaS2);
- boost::numeric::ublas::matrix<complex<InvEnergy2> > highCt_st(4,1);
- boost::numeric::ublas::matrix<complex<InvEnergy2> > highCs_ts_2x2(2,2);
- highCs_ts_2x2(0,0) = highCs_ts(0,0);
- highCs_ts_2x2(1,0) = highCs_ts(1,0);
- highCs_ts_2x2(0,1) = highCs_ts(2,0);
- highCs_ts_2x2(1,1) = highCs_ts(3,0);
- boost::numeric::ublas::matrix<Complex> temp(2,2);
- temp = boost::numeric::ublas::trans(M_N(3));
- boost::numeric::ublas::matrix<complex<InvEnergy2> > highCt_st_2x2(2,2),temp2(2,2);
- axpy_prod_local(highCs_ts_2x2,temp,temp2);
- axpy_prod_local(M_N(2),temp2,highCt_st_2x2);
- highCt_st(0,0) = highCt_st_2x2(0,0);
- highCt_st(1,0) = highCt_st_2x2(1,0);
- highCt_st(2,0) = highCt_st_2x2(0,1);
- highCt_st(3,0) = highCt_st_2x2(1,1);
- highC = highCs_st + highCt_st;
- }
- break;
- case QtQtQQ:
- {
- highC.resize(4,1);
- Process parentCase = QQQQ;
- highC = highEnergyMatching(Q,s,t,u,parentCase,oneLoop,includeAlphaS2);
- double Y = 1.0/6.0; // Hypercharge of the non-3rd-gen doublet (still a quark doublet).
- if (order >= 1) {
- highC(2,0) += y_t*y_t*a2/(4.0*pi*s)*(3.0/2.0-0.5*Ls);
- highC(1,0) += y_t*y_t*a3/(4.0*pi*s)*(1.0/2.0-0.5*Ls);
- highC(3,0) += y_t*y_t*a1*Y/(4.0*pi*s)*(-5.0/12.0-1.0/12.0*Ls);
- }
- }
- break;
- case QQUU:
- Yi = 1./6.; Yf = 2./3.;
- highC.resize(2,1);
- highC(0,0) = 4.0*pi*a3 / s;
- highC(1,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*((a1*a3*(Yi*Yi+Yf*Yf)+a2*a3*C_F_2)*W +
- 2.0*a1*a3*Yi*Yf*fTilde_su);
- highC(1,0) += (1.0/s)*(a1*a1*Yi*Yf*PI1 +
- (a1*a2*Yi*Yf*C_F_2+2.0*a1*a3*Yi*Yf*C_F_3+
- a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- if (includeAlphaS2) {
- highC(0,0) += (1.0/s)*(a3*a3*(X_3_su+(C_d_3-C_A_3)/4.0*fTilde_su));
- highC(1,0) += (1.0/s)*((a3*a3*C_1_3+a1*a1*Yi*Yi*Yf*Yf)*fTilde_su);
- }
- }
- break;
- case QtQtUU:
- {
- highC.resize(2,1);
- Process parentCase = QQUU;
- highC = highEnergyMatching(Q,s,t,u,parentCase,oneLoop,includeAlphaS2);
- double Y = 2./3.;
- if (order >= 1) {
- highC(0,0) += y_t*y_t*a3/(4.0*pi*s)*(1.0/2.0-0.5*Ls);
- highC(1,0) += y_t*y_t*a1*Y/(4.0*pi*s)*(-5.0/12.0-1.0/12.0*Ls);
- }
- }
- break;
- case QQtRtR:
- {
- highC.resize(2,1);
- Process parentCase = QQUU;
- highC = highEnergyMatching(Q,s,t,u,parentCase,oneLoop,includeAlphaS2);
- double Y = 1.0/6.0;
- if (order >= 1) {
- highC(0,0) += y_t*y_t*a3/(4.0*pi*s)*(1.0-Ls);
- highC(1,0) += y_t*y_t*a1*Y/(4.0*pi*s)*(5.0/3.0-2.0/3.0*Ls);
- }
- }
- break;
- case QQDD:
- Yi = 1./6.; Yf = -1./3.;
- highC.resize(2,1);
- highC(0,0) = 4.0*pi*a3 / s;
- highC(1,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*((a1*a3*(Yi*Yi+Yf*Yf)+a2*a3*C_F_2)*W +
- 2.0*a1*a3*Yi*Yf*fTilde_su);
- highC(1,0) += (1.0/s)*(a1*a1*Yi*Yf*PI1 +
- (a1*a2*Yi*Yf*C_F_2+2.0*a1*a3*Yi*Yf*C_F_3+
- a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- if (includeAlphaS2) {
- highC(0,0) += (1.0/s)*(a3*a3*(X_3_su+(C_d_3-C_A_3)/4.0*fTilde_su));
- highC(1,0) += (1.0/s)*((a3*a3*C_1_3+a1*a1*Yi*Yi*Yf*Yf)*fTilde_su);
- }
- }
- break;
- case QtQtDD:
- {
- highC.resize(2,1);
- Process parentCase = QQDD;
- highC = highEnergyMatching(Q,s,t,u,parentCase,oneLoop,includeAlphaS2);
- double Y = -1./3.;
- if (order >= 1) {
- highC(0,0) += y_t*y_t*a3/(4.0*pi*s)*(1.0/2.0-0.5*Ls);
- highC(1,0) += y_t*y_t*a1*Y/(4.0*pi*s)*(-5.0/12.0-1.0/12.0*Ls);
- }
- }
- break;
- case QQLL:
- Yi = 1./6.; Yf = -1./2.;
- highC.resize(2,1);
- highC(0,0) = 4.0*pi*a2 / s;
- highC(1,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(a2*a2*(X_2_st-(C_d_2+C_A_2)/4.0*fTilde_st) +
- (a2*a3*C_F_3 + a1*a2*(Yi*Yi+Yf*Yf))*W -
- 2.0*a1*a2*Yi*Yf*fTilde_st);
- highC(1,0) += (1.0/s)*(-1.0*(a2*a2*C_1_2+a1*a1*Yi*Yi*Yf*Yf)*fTilde_st +
- a1*a1*Yi*Yf*PI1 +
- (a1*a3*Yi*Yf*C_F_3+2.0*a1*a2*Yi*Yf*C_F_2+
- a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- }
- break;
- case QQEE:
- Yi = 1./6.; Yf = -1.;
- highC.resize(1,1);
- highC(0,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(a1*a1*Yi*Yi*Yf*Yf*fTilde_su + a1*a1*Yi*Yf*PI1 +
- (a1*a3*Yi*Yf*C_F_3 + a1*a2*Yi*Yf*C_F_2 +
- a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- }
- break;
- case UUUU:
- Yi = Yf = 2./3.;
- highC.resize(2,1);
- highC(0,0) = 4.0*pi*a3 / s;
- highC(1,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(-2.0*a1*a3*Yi*Yf*fTilde_st +
- a1*a3*(Yi*Yi+Yf*Yf)*W);
- highC(1,0) += (1.0/s)*(-1.0*(a1*a1*Yi*Yi*Yf*Yf)*fTilde_st +
- a1*a1*Yi*Yf*PI1 +
- (2.0*a1*a3*Yi*Yf*C_F_3+a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- if (includeAlphaS2) {
- highC(0,0) += (1.0/s)*(a3*a3*(X_3_st-(C_d_3+C_A_3)/4.0*fTilde_st));
- highC(1,0) += (1.0/s)*(-1.0*(a3*a3*C_1_3)*fTilde_st);
- }
- }
- break;
- case UUUUiden:
- {
- Process parentCase = UUUU;
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highCs_st = highEnergyMatching(Q,s,t,u,parentCase,oneLoop,includeAlphaS2);
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highCs_ts = highEnergyMatching(Q,t,s,u,parentCase,oneLoop,includeAlphaS2);
- boost::numeric::ublas::matrix<complex<InvEnergy2> > highCt_st;
- axpy_prod_local(M_N(3),highCs_ts,highCt_st);
- highC = highCs_st + highCt_st;
- }
- break;
- case tRtRUU:
- {
- highC.resize(2,1);
- Process parentCase = UUUU;
- highC = highEnergyMatching(Q,s,t,u,parentCase,oneLoop,includeAlphaS2);
- double Y = 2./3.;
- if (order >= 1) {
- highC(0,0) += y_t*y_t*a3/(4.0*pi*s)*(1.0-Ls);
- highC(1,0) += y_t*y_t*a1*Y/(4.0*pi*s)*(5.0/3.0-2.0/3.0*Ls);
- }
- }
- break;
- case UUDD:
- Yi = 2./3.; Yf = -1./3.;
- highC.resize(2,1);
- highC(0,0) = 4.0*pi*a3 / s;
- highC(1,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(-2.0*a1*a3*Yi*Yf*fTilde_st +
- a1*a3*(Yi*Yi+Yf*Yf)*W);
- highC(1,0) += (1.0/s)*(-1.0*(a1*a1*Yi*Yi*Yf*Yf)*fTilde_st +
- a1*a1*Yi*Yf*PI1 +
- (2.0*a1*a3*Yi*Yf*C_F_3+a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- if (includeAlphaS2) {
- highC(0,0) += (1.0/s)*(a3*a3*(X_3_st-(C_d_3+C_A_3)/4.0*fTilde_st));
- highC(1,0) += (1.0/s)*(-1.0*(a3*a3*C_1_3)*fTilde_st);
- }
- }
- break;
- case tRtRDD:
- {
- highC.resize(2,1);
- Process parentCase = UUDD;
- highC = highEnergyMatching(Q,s,t,u,parentCase,oneLoop,includeAlphaS2);
- double Y = -1./3.;
- if (order >= 1) {
- highC(0,0) += y_t*y_t*a3/(4.0*pi*s)*(1.0-Ls);
- highC(1,0) += y_t*y_t*a1*Y/(4.0*pi*s)*(5.0/3.0-2.0/3.0*Ls);
- }
- }
- break;
- case UULL:
- Yi = 2./3.; Yf = -0.5;
- highC.resize(1,1);
- highC(0,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(a1*a1*Yi*Yi*Yf*Yf*fTilde_su + a1*a1*Yi*Yf*PI1 +
- (a1*a3*Yi*Yf*C_F_3 + a1*a2*Yi*Yf*C_F_2 +
- a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- }
- break;
- case UUEE:
- Yi = 2./3.; Yf = -1.;
- highC.resize(1,1);
- highC(0,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(-1.0*a1*a1*Yi*Yi*Yf*Yf*fTilde_st + a1*a1*Yi*Yf*PI1 +
- (a1*a3*Yi*Yf*C_F_3 +
- a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- }
- break;
- case DDDD:
- Yi = Yf = -1./3.;
- highC.resize(2,1);
- highC(0,0) = 4.0*pi*a3 / s;
- highC(1,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(-2.0*a1*a3*Yi*Yf*fTilde_st +
- a1*a3*(Yi*Yi+Yf*Yf)*W);
- highC(1,0) += (1.0/s)*(-1.0*(a1*a1*Yi*Yi*Yf*Yf)*fTilde_st +
- a1*a1*Yi*Yf*PI1 +
- (2.0*a1*a3*Yi*Yf*C_F_3+a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- if (includeAlphaS2) {
- highC(0,0) += (1.0/s)*(a3*a3*(X_3_st-(C_d_3+C_A_3)/4.0*fTilde_st));
- highC(1,0) += (1.0/s)*(-1.0*(a3*a3*C_1_3)*fTilde_st);
- }
- }
- break;
- case DDDDiden:
- {
- Process parentCase = DDDD;
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highCs_st = highEnergyMatching(Q,s,t,u,parentCase,oneLoop,includeAlphaS2);
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highCs_ts = highEnergyMatching(Q,t,s,u,parentCase,oneLoop,includeAlphaS2);
- boost::numeric::ublas::matrix<complex<InvEnergy2> > highCt_st;
- axpy_prod_local(M_N(3),highCs_ts,highCt_st);
- highC = highCs_st + highCt_st;
- }
- break;
- case DDLL:
- Yi = -1./3.; Yf = -0.5;
- highC.resize(1,1);
- highC(0,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(a1*a1*Yi*Yi*Yf*Yf*fTilde_su + a1*a1*Yi*Yf*PI1 +
- (a1*a3*Yi*Yf*C_F_3 + a1*a2*Yi*Yf*C_F_2 +
- a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- }
- break;
- case DDEE:
- Yi = -1./3.; Yf = -1.;
- highC.resize(1,1);
- highC(0,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(-1.0*a1*a1*Yi*Yi*Yf*Yf*fTilde_st + a1*a1*Yi*Yf*PI1 +
- (a1*a3*Yi*Yf*C_F_3 +
- a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- }
- break;
- case LLLL:
- Yi = Yf = -0.5;
- highC.resize(2,1);
- highC(0,0) = 4.0*pi*a2 / s;
- highC(1,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(a2*a2*(X_2_st-(C_d_2+C_A_2)/4.0*fTilde_st) +
- 2.0*a1*a2*Yi*Yf*W -
- 2.0*a1*a2*Yi*Yf*fTilde_st);
- highC(1,0) += (1.0/s)*(-1.0*(a2*a2*C_1_2+a1*a1*Yi*Yi*Yf*Yf)*fTilde_st +
- a1*a1*Yi*Yf*PI1 +
- 2.0*(a1*a2*Yi*Yf*C_F_2+a1*a1*Yi*Yi*Yf*Yf)*W);
- }
- break;
- case LLLLiden:
- {
- Process parentCase = LLLL;
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highCs_st = highEnergyMatching(Q,s,t,u,parentCase,oneLoop,includeAlphaS2);
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highCs_ts = highEnergyMatching(Q,t,s,u,parentCase,oneLoop,includeAlphaS2);
- boost::numeric::ublas::matrix<complex<InvEnergy2> > highCt_st;
- axpy_prod_local(M_N(2), highCs_ts, highCt_st);
- highC = highCs_st + highCt_st;
- }
- break;
- case LLEE:
- Yi = -0.5; Yf = -1.;
- highC.resize(1,1);
- highC(0,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(a1*a1*Yi*Yi*Yf*Yf*fTilde_su + a1*a1*Yi*Yf*PI1 +
- (a1*a2*Yi*Yf*C_F_2 +
- a1*a1*(Yi*Yi*Yi*Yf+Yf*Yf*Yf*Yi))*W);
- }
- break;
- case EEEE:
- Yi = Yf = -1.;
- highC.resize(1,1);
- highC(0,0) = 4.0*pi*a1*Yi*Yf / s;
- if (order >= 1) {
- highC(0,0) += (1.0/s)*(-1.0*a1*a1*Yi*Yi*Yf*Yf*fTilde_st + a1*a1*Yi*Yf*PI1 +
- 2.0*a1*a1*Yi*Yi*Yf*Yf*W);
- }
- break;
- case EEEEiden:
- {
- Process parentCase = EEEE;
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highCs_st = highEnergyMatching(Q,s,t,u,parentCase,oneLoop,includeAlphaS2);
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highCs_ts = highEnergyMatching(Q,t,s,u,parentCase,oneLoop,includeAlphaS2);
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highCt_st = highCs_ts;
- highC = highCs_st + highCt_st;
- }
- break;
- default:
- assert(false);
- }
- return highC;
-}
-
-boost::numeric::ublas::matrix<complex<InvEnergy2> >
-HighEnergyMatching::Spin1HighMatching(Energy highScale,
- Energy2 s, Energy2 t, Energy2 u,
- EWProcess::Process process,
- bool oneLoop, bool includeAlphaS2) {
- using Constants::pi;
-
- unsigned int order = !oneLoop ? 0 : 1;
- // (If crossed graphs, swap s and t here)
- Complex L_s = MinusLog(-s/(highScale*highScale));
- Complex L_t = MinusLog(-t/(highScale*highScale));
- Complex L_u = MinusLog(-u/(highScale*highScale));
- Complex L_s2 = L_s*L_s;
- Complex L_t2 = L_t*L_t;
- Complex L_u2 = L_u*L_u;
-
- // Tree-Level:
- // Topology types defined. Note each of these is a vector of 5 entries. They are the coefficients
- // for the dirac structures M_0, M_1, M_4, M_5, and M_6 for vector boson production.
- boost::numeric::ublas::vector<complex<InvEnergy2> > R1(5);
- for(unsigned int ix=0;ix<5;++ix) R1[ix] = ZERO;
- R1[0] = -1.0/t;
- R1[1] = -2.0/t;
- R1[2] = ZERO;
- R1[3] = ZERO;
- R1[4] = ZERO;
- boost::numeric::ublas::vector<complex<InvEnergy2> > R1_bar(5);
- for(unsigned int ix=0;ix<5;++ix) R1_bar[ix] = ZERO;
- R1_bar[0] = -1.0/u;
- boost::numeric::ublas::vector<complex<InvEnergy2> > R2(5);
- for(unsigned int ix=0;ix<5;++ix) R2[ix] = ZERO;
- R2[1] = -1.0/s*2.0;
- // Topologies T1:
- boost::numeric::ublas::vector<complex<InvEnergy2> > T1a(5);
- for(unsigned int ix=0;ix<5;++ix) T1a[ix] = ZERO;
- T1a[0] = 1.0/(t*u)*(-3.0*t*L_s2-(s+4.0*t)*L_t2+2.0*(s+4.0*t)*L_s*L_t+2.0*u*L_t-
- pi*pi*(7.0/6.0*s+25.0/6.0*t)-4.0*u);
- T1a[1] = 1.0/(u*u*t*s)*(0.5*t*(9.0*s*s+14.0*s*t+7.0*t*t)*L_s2+s*(2.0*s+t)*(s+2.0*t)*L_t2-
- 2.0*(2.0*s*s*s+9.0*s*s*t+10.0*s*t*t+4.0*t*t*t)*L_s*L_t-
- 2.0*t*t*u*L_s-2.0*u*s*(2.0*s+3.0*t)*L_t+
- pi*pi*(7.0/3.0*s*s*s+125.0/12.0*s*s*t+71.0/6.0*s*t*t+
- 19.0/4.0*t*t*t)-
- 8.0*s*s*s-20.0*s*s*t-16.0*s*t*t-4.0*t*t*t);
- T1a[2] = 1.0/(t*u*u)*(-t*(3.0*s+4.0*t)*L_s2-(s*s+5.0*s*t+5.0*t*t)*L_t2+
- 2.0*t*(3.0*s+4.0*t)*L_s*L_t+2.0*u*t*(2.0*s+t)*L_s/s-
- 2.0*u*t*L_t+pi*pi*(s*s/6.0-8.0/3.0*s*t-23.0/6.0*t*t)+
- 4.0*t*t*t/s+4.0*s*t+8.0*t*t);
- T1a[3] = T1a[2];
- T1a[4] = GeV2/(t*u*u*u)*(-4.0*t*(s+2.0*t)*(L_s-L_t)*(L_s-L_t)+
- 4.0*u*(3.0*s+5.0*t)*(L_s-L_t)-4.0*pi*pi*t*(s+2.0*t)-4.0*u*u);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T1b(5);
- for(unsigned int ix=0;ix<5;++ix) T1b[ix] = ZERO;
- T1b[0] = 1.0/(t*u*s*s)*(-s*t*(2.0*s+3.0*t)*L_u2+s*u*(s+3.0*t)*L_t2+
- 2.0*s*(s*s+3.0*s*t+3.0*t*t)*L_u*L_t+s*s*t*L_u+s*s*u*L_t-
- pi*pi*(7.0/6.0*s*s*s+3.0*s*s*t+3.0*s*t*t)+2.0*s*s*s);
- T1b[1] = 1.0/(t*s*s*u)*(3.0*s*t*u*L_u2+s*u*(2.0*s+3.0*t)*L_t2-
- 2.0*s*u*(2.0*s+3.0*t)*L_u*L_t+2.0*s*s*u*L_t-
- pi*pi*(7.0/3.0*s*s*s+16.0/3.0*s*s*t+3.0*s*t*t)+
- 4.0*s*s*s+4.0*s*s*t);
- T1b[2] = 1.0/(t*u*s*s)*(-3.0*s*t*u*(L_u-L_t)*(L_u-L_t)+4.0*s*s*t*L_u+4.0*s*s*u*L_t+
- pi*pi*(3.0*s*s*t+3.0*s*t*t)+8.0*s*s*s);
- T1b[3] = 1.0/(t*u*s*s)*(s*t*(2.0*s+3.0*t)*L_u2-s*u*(s+3.0*t)*L_t2+6.0*s*t*u*L_u*L_t+
- pi*pi*(-1.0/6.0*s*s*s+3.0*s*s*t+3.0*s*t*t));
- T1b[4] = 12.0*GeV2/(t*u)*(L_t-L_u);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T1c(5);
- for(unsigned int ix=0;ix<5;++ix) T1c[ix] = ZERO;
- T1c[0] = 1.0/t*(2.0*L_s*L_t-7.0*pi*pi/6.0-L_t2);
- T1c[1] = 1.0/(t*u*u)*(s*t*L_s2-(2.0*s*s+3.0*s*t+2.0*t*t)*L_t2+
- 2.0*(2.0*s*s+3.0*s*t+2.0*t*t)*L_s*L_t+2.0*t*u*(L_s-L_t)-
- pi*pi*(7.0/3.0*s*s+11.0/3.0*s*t+7.0/3.0*t*t));
- T1c[2] = 1.0/(t*u*u)*(t*(3.0*s+2.0*t)*(L_s-L_t)*(L_s-L_t)+2.0*u*t*L_s+
- 2.0*u*(2.0*s+t)*L_t+pi*pi*t*(3.0*s+2.0*t)+8.0*u*u);
- T1c[3] = T1c[2];
- T1c[4] = GeV2/(t*u*u*u)*(4.0*t*(2.0*s+t)*(L_s-L_t)*(L_s-L_t)-4.0*u*(3.0*s+t)*(L_s-L_t)+
- 4.0*pi*pi*t*(2.0*s+t)-4.0*u*u);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T1d(5);
- for(unsigned int ix=0;ix<5;++ix) T1d[ix] = ZERO;
- T1d[2] = 1.0/s*(-2.0*L_s+4.0);
- T1d[3] = T1d[2];
- boost::numeric::ublas::vector<complex<InvEnergy2> > T1a_bar(5);
- for(unsigned int ix=0;ix<5;++ix) T1a_bar[ix] = ZERO;
- T1a_bar[0] = 1.0/(u*t)*(-3.0*u*L_s2-(s+4.0*u)*L_u2+2.0*(s+4.0*u)*L_s*L_u+2.0*t*L_u-
- pi*pi*(7.0/6.0*s+25.0/6.0*u)-4.0*t);
- T1a_bar[1] = 2.0*T1a_bar[0] -
- 1.0/(t*t*u*s)*(0.5*u*(9.0*s*s+14.0*s*u+7.0*u*u)*L_s2+s*(2.0*s+u)*(s+2.0*u)*L_u2-
- 2.0*(2.0*s*s*s+9.0*s*s*u+10.0*s*u*u+4.0*u*u*u)*L_s*L_u-
- 2.0*u*u*t*L_s-2.0*t*s*(2.0*s+3.0*u)*L_u+
- pi*pi*(7.0/3.0*s*s*s+125.0/12.0*s*s*u+71.0/6.0*s*u*u+
- 19.0/4.0*u*u*u)-
- 8.0*s*s*s-20.0*s*s*u-16.0*s*u*u-4.0*u*u*u);
- T1a_bar[2] = 1.0/(u*t*t)*(-u*(3.0*s+4.0*u)*L_s2-(s*s+5.0*s*u+5.0*u*u)*L_u2+
- 2.0*u*(3.0*s+4.0*u)*L_s*L_u+2.0*t*u*(2.0*s+u)*L_s/s-
- 2.0*t*u*L_u+pi*pi*(s*s/6.0-8.0/3.0*s*u-23.0/6.0*u*u)+
- 4.0*u*u*u/s+4.0*s*u+8.0*u*u);
- T1a_bar[3] = T1a_bar[2];
- T1a_bar[4] = -GeV2/(u*t*t*t)*(-4.0*u*(s+2.0*u)*(L_s-L_u)*(L_s-L_u)+
- 4.0*t*(3.0*s+5.0*u)*(L_s-L_u)-4.0*pi*pi*u*(s+2.0*u)-4.0*t*t);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T1b_bar(5);
- for(unsigned int ix=0;ix<5;++ix) T1b_bar[ix] = ZERO;
- T1b_bar[0] = 1.0/(u*t*s*s)*(-s*u*(2.0*s+3.0*u)*L_t2+s*t*(s+3.0*u)*L_u2+
- 2.0*s*(s*s+3.0*s*u+3.0*u*u)*L_t*L_u+
- s*s*u*L_t+s*s*t*L_u-
- pi*pi*(7.0/6.0*s*s*s+3.0*s*s*u+3.0*s*u*u)+2.0*s*s*s);
- T1b_bar[1] = 2.0*T1b_bar[0] -
- 1.0/(u*s*s*t)*(3.0*s*u*t*L_t2+s*t*(2.0*s+3.0*u)*L_u2-
- 2.0*s*t*(2.0*s+3.0*u)*L_t*L_u+2.0*s*s*t*L_u-
- pi*pi*(7.0/3.0*s*s*s+16.0/3.0*s*s*u+3.0*s*u*u)+
- 4.0*s*s*s+4.0*s*s*u);
- T1b_bar[3] = 1.0/(u*t*s*s)*(-3.0*s*u*t*(L_t-L_u)*(L_t-L_u)+4.0*s*s*u*L_t+4.0*s*s*t*L_u+
- pi*pi*(3.0*s*s*u+3.0*s*u*u)+8.0*s*s*s);
- T1b_bar[2] = 1.0/(u*t*s*s)*(s*u*(2.0*s+3.0*u)*L_t2-s*t*(s+3.0*u)*L_u2+6.0*s*u*t*L_t*L_u+
- pi*pi*(-1.0/6.0*s*s*s+3.0*s*s*u+3.0*s*u*u));
- T1b_bar[4] = -12.0*GeV2/(u*t)*(L_u-L_t);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T1c_bar(5);
- for(unsigned int ix=0;ix<5;++ix) T1c_bar[ix] = ZERO;
- T1c_bar[0] = 1.0/u*(2.0*L_s*L_u-7.0*pi*pi/6.0-L_u2);
- T1c_bar[1] = 2.0*T1c_bar[0] -
- 1.0/(u*t*t)*(s*u*L_s2-(2.0*s*s+3.0*s*u+2.0*u*u)*L_u2+
- 2.0*(2.0*s*s+3.0*s*u+2.0*u*u)*L_s*L_u+2.0*u*t*(L_s-L_u)-
- pi*pi*(7.0/3.0*s*s+11.0/3.0*s*u+7.0/3.0*u*u));
- T1c_bar[2] = 1.0/(u*t*t)*(u*(3.0*s+2.0*u)*(L_s-L_u)*(L_s-L_u)+2.0*t*u*L_s+
- 2.0*t*(2.0*s+u)*L_u+pi*pi*u*(3.0*s+2.0*u)+8.0*t*t);
- T1c_bar[3] = T1c_bar[2];
- T1c_bar[4] = -GeV2/(u*t*t*t)*(4.0*u*(2.0*s+u)*(L_s-L_u)*(L_s-L_u)-4.0*t*(3.0*s+u)*(L_s-L_u)+
- 4.0*pi*pi*u*(2.0*s+u)-4.0*t*t);
- // Topologies T2:
- boost::numeric::ublas::vector<complex<InvEnergy2> > T2a(5);
- for(unsigned int ix=0;ix<5;++ix) T2a[ix] = ZERO;
- T2a[1] = 1.0/s*(L_s/6.0-11.0/18.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T2b(5);
- for(unsigned int ix=0;ix<5;++ix) T2b[ix] = ZERO;
- T2b[1] = 1.0/s*(-2.0/3.0*L_s+22.0/9.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T2c(5);
- for(unsigned int ix=0;ix<5;++ix) T2c[ix] = ZERO;
- T2c[1] = 1.0/s*(3.0/2.0*L_s2-17.0/2.0*L_s-pi*pi/4.0+95.0/6.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T2d(5);
- for(unsigned int ix=0;ix<5;++ix) T2d[ix] = ZERO;
- T2d[1] = 1.0/s*(-4.0/3.0*L_s+14.0/9.0);
- // Topologies T3:
- boost::numeric::ublas::vector<complex<InvEnergy2> > T3a(5);
- for(unsigned int ix=0;ix<5;++ix) T3a[ix] = ZERO;
- T3a[0] = 1.0/t*(L_t2-pi*pi/6.0);
- T3a[1] = 2.0*T3a[0];
- T3a[3] = 1.0/t*(-L_t2+pi*pi/6.0+2.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T3b(5);
- for(unsigned int ix=0;ix<5;++ix) T3b[ix] = ZERO;
- T3b[0] = 1.0/t*(-L_t+4.0);
- T3b[1] = 2.0*T3b[0];
- T3b[3] = 1.0/t*(4.0*L_t-10.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T3a_bar(5);
- for(unsigned int ix=0;ix<5;++ix) T3a_bar[ix] = ZERO;
- T3a_bar[0] = 1.0/u*(L_u2-pi*pi/6.0);
- T3a_bar[2] = 1.0/u*(-L_u2+pi*pi/6.0+2.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T3b_bar(5);
- for(unsigned int ix=0;ix<5;++ix) T3b_bar[ix] = ZERO;
- T3b_bar[0] = 1.0/u*(-L_u+4.0);
- T3b_bar[2] = 1.0/u*(4.0*L_u-10.0);
- // Topologies T4:
- boost::numeric::ublas::vector<complex<InvEnergy2> > T4a(5);
- for(unsigned int ix=0;ix<5;++ix) T4a[ix] = ZERO;
- T4a[0] = 1.0/t*(L_t2-pi*pi/6.0);
- T4a[1] = 2.0*T4a[0];
- T4a[2] = 1.0/t*(-L_t2+pi*pi/6.0+2.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T4b(5);
- for(unsigned int ix=0;ix<5;++ix) T4b[ix] = ZERO;
- T4b[0] = 1.0/t*(-L_t+4.0);
- T4b[1] = 2.0*T4b[0];
- T4b[2] = 1.0/t*(4.0*L_t-10.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T4a_bar(5);
- for(unsigned int ix=0;ix<5;++ix) T4a_bar[ix] = ZERO;
- T4a_bar[0] = 1.0/u*(L_u2-pi*pi/6.0);
- T4a_bar[3] = 1.0/u*(-L_u2+pi*pi/6.0+2.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T4b_bar(5);
- for(unsigned int ix=0;ix<5;++ix) T4b_bar[ix] = ZERO;
- T4b_bar[0] = 1.0/u*(-L_u+4.0);
- T4b_bar[3] = 1.0/u*(4.0*L_u-10.0);
- // Topologies T5:
- boost::numeric::ublas::vector<complex<InvEnergy2> > T5a(5);
- for(unsigned int ix=0;ix<5;++ix) T5a[ix] = ZERO;
- T5a[1] = 1.0/s*(2.0*L_s-4.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T5b(5);
- for(unsigned int ix=0;ix<5;++ix) T5b[ix] = ZERO;
- T5b[1] = 1.0/s*(-2.0*L_s2+6.0*L_s-16.0+pi*pi/3.0);
- // Topologies T6:
- boost::numeric::ublas::vector<complex<InvEnergy2> > T6a(5);
- for(unsigned int ix=0;ix<5;++ix) T6a[ix] = ZERO;
- T6a[1] = 1.0/s*(-19.0/6.0*L_s+58.0/9.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T6b(5);
- for(unsigned int ix=0;ix<5;++ix) T6b[ix] = ZERO;
- T6b[1] = 1.0/s*(-1.0/6.0*L_s+4.0/9.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T6c(5);
- for(unsigned int ix=0;ix<5;++ix) T6c[ix] = ZERO;
- T6c[1] = 1.0/s*(2.0/3.0*L_s-16.0/9.0);
- boost::numeric::ublas::vector<complex<InvEnergy2> > T6d(5);
- for(unsigned int ix=0;ix<5;++ix) T6d[ix] = ZERO;
- T6d[1] = 1.0/s*(4.0/3.0*L_s-20.0/9.0);
- // Topology T7:
- boost::numeric::ublas::vector<complex<InvEnergy2> > T7(5);
- for(unsigned int ix=0;ix<5;++ix) T7[ix] = ZERO;
- T7[0] = 1.0/t*(-L_t+1.0);
- T7[1] = 2.0*T7[0];
- boost::numeric::ublas::vector<complex<InvEnergy2> > T7_bar(5);
- for(unsigned int ix=0;ix<5;++ix) T7_bar[ix] = ZERO;
- T7_bar[0] = 1.0/u*(-L_u+1.0);
- // Group Theory Factors / SM parameters needed for matrix elements:
- double a1 = ElectroWeakReweighter::coupling()->a1(highScale);
- double a2 = ElectroWeakReweighter::coupling()->a2(highScale);
- double a3 = ElectroWeakReweighter::coupling()->a3(highScale);
- double y_t = ElectroWeakReweighter::coupling()->y_t(highScale);
- // Traces over complex scalars and weyl fermions.
- double T_CS_3 = 0.0;
- double T_CS_2 = 0.5;
- //double T_CS_1 = 0.5;
- double T_WF_3 = 2.0*3.0;
- double T_WF_2 = 2.0*3.0;
- //double T_WF_1 = 10.0/3.0*3.0;
- double C_A_3 = 3.0;
- double C_A_2 = 2.0;
- double C_A_1 = 0.0;
- double C_F_3 = 4.0/3.0;
- double C_F_2 = 3.0/4.0;
- double C_F_1 = 1.0;
- // This is the coefficient of the delta term in G_TT
- double G_TT = 0.5;
- // This is the coeffidient of d^ABC in G_TT (non-zero for SU(3))
- double G_TT_3_D = 0.25*C_A_3;
- double G_f = 1.0;
- // Factors TBD after fermion helicity is specified:
- double Y_Q(0.), G_Plus_U1(0.);
- double G_Plus_SU2 = 0.25;
- double G_Plus_SU3 = 1./6.;
- double G_Plus_SU3_D = 0.5;
- double Lambda_Q(0.);
- // the _s and _ew are the alpha3 and alpha1/2 parts of Lambda_Q
- double Lambda_Q_s(0.);
- double Lambda_Q_ew(0.);
- double rho12(0.), rho13(0.);
- double rho23 = sqrt(a2*a3);
- double tRorQ = 1.0;
- boost::numeric::ublas::matrix<complex<InvEnergy2> > highC(1,1);
- switch (process) {
- case QQWW: case LLWW:
- {
- // Finish Group Theory Factors:
- if (process==QQWW) {
- Y_Q = 1.0/6.0;
- G_Plus_U1 = Y_Q*Y_Q;
- Lambda_Q = C_F_3*a3 + C_F_2*a2 + Y_Q*Y_Q*C_F_1*a1;
- rho12 = Y_Q*sqrt(a1*a2);
- }
- else if (process==LLWW) {
- Y_Q = -1.0/2.0;
- G_Plus_U1 = Y_Q*Y_Q;
- Lambda_Q = C_F_2*a2 + Y_Q*Y_Q*C_F_1*a1;
- rho12 = Y_Q*sqrt(a1*a2);
- }
- highC.resize(5,5);
- for (int i=0; i<5; i++) {
- highC(0,i) = G_Plus_SU2*(4.0*pi*a2)*(R1[i]+R1_bar[i]);
- highC(1,i) = G_f*4.0*pi*a2*(-0.5*R1[i]+0.5*R1_bar[i]-R2[i]);
- highC(2,i) = rho12*4.0*pi*(R1[i]+R1_bar[i]);
- highC(3,i) = rho12*4.0*pi*(R1[i]+R1_bar[i]);
- highC(4,i) = G_Plus_U1*(4.0*pi*a1)*(R1[i]+R1_bar[i]);
- if (order>=1) {
- highC(0,i) += G_Plus_SU2*((-0.5*a2*a2*C_A_2)*(T1b[i]+T1b_bar[i])+
- a2*(Lambda_Q-a2*C_A_2)*(T1c[i]+T1c_bar[i])+
- 0.5*a2*a2*C_A_2*(T3a[i]+T3a_bar[i])+
- a2*(Lambda_Q-0.5*a2*C_A_2)*(T3b[i]+T3b_bar[i])+
- 0.5*a2*a2*C_A_2*(T4a[i]+T4a_bar[i])+
- a2*(Lambda_Q-0.5*a2*C_A_2)*(T4b[i]+T4b_bar[i])+
- a2*Lambda_Q*(T7[i]+T7_bar[i])) +
- G_TT*(-a2*a2*(T1a[i]+T1a_bar[i])+a2*a2*(T1b[i]+T1b_bar[i])+
- a2*a2*(T1c[i]+T1c_bar[i])+2.0*a2*a2*T1d[i]);
- highC(1,i) += G_f*(0.25*a2*a2*C_A_2*(T1a[i]-T1a_bar[i])+
- a2*(0.25*a2*C_A_2-0.5*Lambda_Q)*(T1c[i]-T1c_bar[i])+
- 0.5*a2*a2*C_A_2*T2a[i]+a2*a2*T_CS_2*T2b[i]-
- 0.5*a2*a2*C_A_2*T2c[i]+a2*a2*T_WF_2*T2d[i]-
- 0.25*a2*a2*C_A_2*(T3a[i]-T3a_bar[i])-
- 0.5*a2*(Lambda_Q-0.5*a2*C_A_2)*(T3b[i]-T3b_bar[i])-
- 0.25*a2*a2*C_A_2*(T4a[i]-T4a_bar[i])-
- 0.5*a2*(Lambda_Q-0.5*a2*C_A_2)*(T4b[i]-T4b_bar[i])+
- 0.5*a2*a2*C_A_2*T5a[i]+a2*(Lambda_Q-0.5*a2*C_A_2)*T5b[i]+
- a2*a2*C_A_2*T6a[i]+a2*a2*C_A_2*T6b[i]+
- a2*a2*T_CS_2*T6c[i]+a2*a2*T_WF_2*T6d[i]-
- 0.5*a2*Lambda_Q*(T7[i]-T7_bar[i]));
- highC(2,i) += rho12*(-0.5*a1*C_A_1*T1b[i]-0.5*a2*C_A_2*T1b_bar[i]+
- (Lambda_Q-0.5*a1*C_A_1-0.5*a2*C_A_2)*(T1c[i]+T1c_bar[i])+
- 0.5*a1*C_A_1*T3a[i]+0.5*a2*C_A_2*T3a_bar[i]+
- (Lambda_Q-0.5*a1*C_A_1)*T3b[i]+(Lambda_Q-0.5*a2*C_A_2)*T3b_bar[i]+
- 0.5*a2*C_A_2*T4a[i]+0.5*a1*C_A_1*T4a_bar[i]+
- (Lambda_Q-0.5*a2*C_A_2)*T4b[i]+(Lambda_Q-0.5*a1*C_A_1)*T4b_bar[i]+
- Lambda_Q*(T7[i]+T7_bar[i]));
- highC(3,i) += rho12*(-0.5*a2*C_A_2*T1b[i]-0.5*a1*C_A_1*T1b_bar[i]+
- (Lambda_Q-0.5*a2*C_A_2-0.5*a1*C_A_1)*(T1c[i]+T1c_bar[i])+
- 0.5*a2*C_A_2*T3a[i]+0.5*a1*C_A_1*T3a_bar[i]+
- (Lambda_Q-0.5*a2*C_A_2)*T3b[i]+(Lambda_Q-0.5*a1*C_A_1)*T3b_bar[i]+
- 0.5*a1*C_A_1*T4a[i]+0.5*a2*C_A_2*T4a_bar[i]+
- (Lambda_Q-0.5*a1*C_A_1)*T4b[i]+(Lambda_Q-0.5*a2*C_A_2)*T4b_bar[i]+
- Lambda_Q*(T7[i]+T7_bar[i]));
- highC(4,i) += G_Plus_U1*((-0.5*a1*a1*C_A_1)*(T1b[i]+T1b_bar[i])+
- a1*(Lambda_Q-a1*C_A_1)*(T1c[i]+T1c_bar[i])+
- 0.5*a1*a1*C_A_1*(T3a[i]+T3a_bar[i])+
- a1*(Lambda_Q-0.5*a1*C_A_1)*(T3b[i]+T3b_bar[i])+
- 0.5*a1*a1*C_A_1*(T4a[i]+T4a_bar[i])+
- a1*(Lambda_Q-0.5*a1*C_A_1)*(T4b[i]+T4b_bar[i])+
- a1*Lambda_Q*(T7[i]+T7_bar[i]));
- }
- }
- }
- break;
- case UUBB: case DDBB: case EEBB:
- {
- // Finish Group Theory Factors:
- if (process==UUBB) {
- Y_Q = 2.0/3.0;
- G_Plus_U1 = Y_Q*Y_Q;
- Lambda_Q = C_F_3*a3 + Y_Q*Y_Q*C_F_1*a1;
- }
- else if (process==DDBB) {
- Y_Q = -1.0/3.0;
- G_Plus_U1 = Y_Q*Y_Q;
- Lambda_Q = C_F_3*a3 + Y_Q*Y_Q*C_F_1*a1;
- }
- else if (process==EEBB) {
- Y_Q = -1.0;
- G_Plus_U1 = Y_Q*Y_Q;
- Lambda_Q = Y_Q*Y_Q*C_F_1*a1;
- }
- highC.resize(1,5);
- for (int i=0; i<5; i++) {
- highC(0,i) = G_Plus_U1*(4.0*pi*a1)*(R1[i]+R1_bar[i]);
- if (order>=1) {
- highC(0,i) += G_Plus_U1*((-0.5*a1*a1*C_A_1)*(T1b[i]+T1b_bar[i])+
- a1*(Lambda_Q-a1*C_A_1)*(T1c[i]+T1c_bar[i])+
- 0.5*a1*a1*C_A_1*(T3a[i]+T3a_bar[i])+
- a1*(Lambda_Q-0.5*a1*C_A_1)*(T3b[i]+T3b_bar[i])+
- 0.5*a1*a1*C_A_1*(T4a[i]+T4a_bar[i])+
- a1*(Lambda_Q-0.5*a1*C_A_1)*(T4b[i]+T4b_bar[i])+
- a1*Lambda_Q*(T7[i]+T7_bar[i]));
- }
- }
- }
- break;
- case QQWG:
- {
- // Finish Group Theory Factors:
- Y_Q = 1./6.;
- Lambda_Q = C_F_3*a3 + C_F_2*a2 + Y_Q*Y_Q*C_F_1*a1;
-
- highC.resize(1,5);
-
- for (int i=0; i<5; i++) {
- highC(0,i) = rho23*4.0*pi*(R1[i]+R1_bar[i]);
-
- if (order>=1) {
-
- highC(0,i) += rho23*(-0.5*a3*C_A_3*T1b[i]-0.5*a2*C_A_2*T1b_bar[i]+
- (Lambda_Q-0.5*a3*C_A_3-0.5*a2*C_A_2)*(T1c[i]+T1c_bar[i])+
- 0.5*a3*C_A_3*T3a[i]+0.5*a2*C_A_2*T3a_bar[i]+
- (Lambda_Q-0.5*a3*C_A_3)*T3b[i]+(Lambda_Q-0.5*a2*C_A_2)*T3b_bar[i]+
- 0.5*a2*C_A_2*T4a[i]+0.5*a3*C_A_3*T4a_bar[i]+
- (Lambda_Q-0.5*a2*C_A_2)*T4b[i]+(Lambda_Q-0.5*a3*C_A_3)*T4b_bar[i]+
- Lambda_Q*(T7[i]+T7_bar[i]));
- }
- }
- }
- break;
- case QQBG:
- {
- // Finish Group Theory Factors:
- Y_Q = 1.0/6.0;
- Lambda_Q = C_F_3*a3 + C_F_2*a2 + Y_Q*Y_Q*C_F_1*a1;
- rho13 = Y_Q*sqrt(a1*a3);
-
- highC.resize(1,5);
-
- for (int i=0; i<5; i++) {
- highC(0,i) = rho13*4.0*pi*(R1[i]+R1_bar[i]);
-
- if (order>=1) {
-
- highC(0,i) += rho13*(-0.5*a3*C_A_3*T1b[i]-0.5*a1*C_A_1*T1b_bar[i]+
- (Lambda_Q-0.5*a3*C_A_3-0.5*a1*C_A_1)*(T1c[i]+T1c_bar[i])+
- 0.5*a3*C_A_3*T3a[i]+0.5*a1*C_A_1*T3a_bar[i]+
- (Lambda_Q-0.5*a3*C_A_3)*T3b[i]+(Lambda_Q-0.5*a1*C_A_1)*T3b_bar[i]+
- 0.5*a1*C_A_1*T4a[i]+0.5*a3*C_A_3*T4a_bar[i]+
- (Lambda_Q-0.5*a1*C_A_1)*T4b[i]+(Lambda_Q-0.5*a3*C_A_3)*T4b_bar[i]+
- Lambda_Q*(T7[i]+T7_bar[i]));
- }
- }
- }
- break;
- case UUBG: case DDBG:
- {
- // Finish Group Theory Factors:
- if (process==UUBG) {
- Y_Q = 2.0/3.0;
- Lambda_Q = C_F_3*a3 + Y_Q*Y_Q*C_F_1*a1;
- rho13 = Y_Q*sqrt(a1*a3);
- }
- else if (process==DDBG) {
- Y_Q = -1.0/3.0;
- Lambda_Q = C_F_3*a3 + Y_Q*Y_Q*C_F_1*a1;
- rho13 = Y_Q*sqrt(a1*a3);
- }
-
- highC.resize(1,5);
-
- for (int i=0; i<5; i++) {
- highC(0,i) = rho13*4.0*pi*(R1[i]+R1_bar[i]);
-
- if (order>=1) {
-
- highC(0,i) += rho13*(-0.5*a3*C_A_3*T1b[i]-0.5*a1*C_A_1*T1b_bar[i]+
- (Lambda_Q-0.5*a3*C_A_3-0.5*a1*C_A_1)*(T1c[i]+T1c_bar[i])+
- 0.5*a3*C_A_3*T3a[i]+0.5*a1*C_A_1*T3a_bar[i]+
- (Lambda_Q-0.5*a3*C_A_3)*T3b[i]+(Lambda_Q-0.5*a1*C_A_1)*T3b_bar[i]+
- 0.5*a1*C_A_1*T4a[i]+0.5*a3*C_A_3*T4a_bar[i]+
- (Lambda_Q-0.5*a1*C_A_1)*T4b[i]+(Lambda_Q-0.5*a3*C_A_3)*T4b_bar[i]+
- Lambda_Q*(T7[i]+T7_bar[i]));
- }
- }
- }
- break;
- case QQGG: case QtQtGG: case UUGG:
- case tRtRGG: case DDGG:
- {
- // Finish Group Theory Factors:
- if (process==QQGG || process==QtQtGG) {
- Y_Q = 1.0/6.0;
- Lambda_Q = C_F_3*a3 + C_F_2*a2 + Y_Q*Y_Q*C_F_1*a1;
- Lambda_Q_s = C_F_3*a3;
- Lambda_Q_ew = C_F_2*a2 + Y_Q*Y_Q*C_F_1*a1;
- }
- else if (process==UUGG || process==tRtRGG) {
- Y_Q = 2.0/3.0;
- Lambda_Q = C_F_3*a3 + Y_Q*Y_Q*C_F_1*a1;
- Lambda_Q_s = C_F_3*a3;
- Lambda_Q_ew = Y_Q*Y_Q*C_F_1*a1;
- }
- else if (process==DDGG || process==tRtRGG) {
- Y_Q = -1.0/3.0;
- Lambda_Q = C_F_3*a3 + Y_Q*Y_Q*C_F_1*a1;
- Lambda_Q_s = C_F_3*a3;
- Lambda_Q_ew = Y_Q*Y_Q*C_F_1*a1;
- }
-
- highC.resize(3,5);
-
- for (int i=0; i<5; i++) {
- highC(0,i) = G_Plus_SU3*(4.0*pi*a3)*(R1[i]+R1_bar[i]);
- highC(1,i) = G_Plus_SU3_D*(4.0*pi*a3)*(R1[i]+R1_bar[i]);
- highC(2,i) = G_f*4.0*pi*a3*(-0.5*R1[i]+0.5*R1_bar[i]-R2[i]);
-
- if (order>=1) {
- highC(0,i) += G_Plus_SU3*(a3*(Lambda_Q_ew)*(T1c[i]+T1c_bar[i])+
- a3*(Lambda_Q_ew)*(T3b[i]+T3b_bar[i])+
- a3*(Lambda_Q_ew)*(T4b[i]+T4b_bar[i])+
- a3*Lambda_Q_ew*(T7[i]+T7_bar[i]));
- highC(1,i) += G_Plus_SU3_D*(a3*(Lambda_Q_ew)*(T1c[i]+T1c_bar[i])+
- a3*(Lambda_Q_ew)*(T3b[i]+T3b_bar[i])+
- a3*(Lambda_Q_ew)*(T4b[i]+T4b_bar[i])+
- a3*Lambda_Q_ew*(T7[i]+T7_bar[i]));
- highC(2,i) += G_f*(a3*(-0.5*Lambda_Q_ew)*(T1c[i]-T1c_bar[i])-
- 0.5*a3*(Lambda_Q_ew)*(T3b[i]-T3b_bar[i])-
- 0.5*a3*(Lambda_Q_ew)*(T4b[i]-T4b_bar[i])+
- a3*(Lambda_Q_ew)*T5b[i]-
- 0.5*a3*Lambda_Q_ew*(T7[i]-T7_bar[i]));
- if (includeAlphaS2) {
- highC(0,i) += G_Plus_SU3*((-0.5*a3*a3*C_A_3)*(T1b[i]+T1b_bar[i])+
- a3*(Lambda_Q_s-a3*C_A_3)*(T1c[i]+T1c_bar[i])+
- 0.5*a3*a3*C_A_3*(T3a[i]+T3a_bar[i])+
- a3*(Lambda_Q_s-0.5*a3*C_A_3)*(T3b[i]+T3b_bar[i])+
- 0.5*a3*a3*C_A_3*(T4a[i]+T4a_bar[i])+
- a3*(Lambda_Q_s-0.5*a3*C_A_3)*(T4b[i]+T4b_bar[i])+
- a3*Lambda_Q_s*(T7[i]+T7_bar[i])) +
- G_TT*(-a3*a3*(T1a[i]+T1a_bar[i])+a3*a3*(T1b[i]+T1b_bar[i])+
- a3*a3*(T1c[i]+T1c_bar[i])+2.0*a3*a3*T1d[i]);
- highC(1,i) += G_Plus_SU3_D*((-0.5*a3*a3*C_A_3)*(T1b[i]+T1b_bar[i])+
- a3*(Lambda_Q_s-a3*C_A_3)*(T1c[i]+T1c_bar[i])+
- 0.5*a3*a3*C_A_3*(T3a[i]+T3a_bar[i])+
- a3*(Lambda_Q_s-0.5*a3*C_A_3)*(T3b[i]+T3b_bar[i])+
- 0.5*a3*a3*C_A_3*(T4a[i]+T4a_bar[i])+
- a3*(Lambda_Q_s-0.5*a3*C_A_3)*(T4b[i]+T4b_bar[i])+
- a3*Lambda_Q_s*(T7[i]+T7_bar[i])) +
- G_TT_3_D*(-a3*a3*(T1a[i]+T1a_bar[i])+a3*a3*(T1b[i]+T1b_bar[i])+
- a3*a3*(T1c[i]+T1c_bar[i])+2.0*a3*a3*T1d[i]);
- highC(2,i) += G_f*(0.25*a3*a3*C_A_3*(T1a[i]-T1a_bar[i])+
- a3*(0.25*a3*C_A_3-0.5*Lambda_Q_s)*(T1c[i]-T1c_bar[i])+
- 0.5*a3*a3*C_A_3*T2a[i]+a3*a3*T_CS_3*T2b[i]-
- 0.5*a3*a3*C_A_3*T2c[i]+a3*a3*T_WF_3*T2d[i]-
- 0.25*a3*a3*C_A_3*(T3a[i]-T3a_bar[i])-
- 0.5*a3*(Lambda_Q_s-0.5*a3*C_A_3)*(T3b[i]-T3b_bar[i])-
- 0.25*a3*a3*C_A_3*(T4a[i]-T4a_bar[i])-
- 0.5*a3*(Lambda_Q_s-0.5*a3*C_A_3)*(T4b[i]-T4b_bar[i])+
- 0.5*a3*a3*C_A_3*T5a[i]+a3*(Lambda_Q_s-0.5*a3*C_A_3)*T5b[i]+
- a3*a3*C_A_3*T6a[i]+a3*a3*C_A_3*T6b[i]+
- a3*a3*T_CS_3*T6c[i]+a3*a3*T_WF_3*T6d[i]-
- 0.5*a3*Lambda_Q_s*(T7[i]-T7_bar[i]));
- }
- }
- }
-
- if ( (process==QtQtGG||process==tRtRGG) && order>=1) {
-
- if (process==tRtRGG) {
- tRorQ = 2.0;
- }
- else {
- tRorQ = 1.0;
- }
- highC(0,0) += tRorQ*(-1.0*(s*((s+t)*L_t - t*L_u)*y_t*y_t*a3)/(48.*pi*t*u*s));
- highC(0,1) += tRorQ*((s*L_t*y_t*y_t*a3)/(24.*pi*t*s));
- highC(0,2) += tRorQ*(-(s*s*y_t*y_t*a3)/((24.*pi*s*t+24.*pi*t*t)*s));
- highC(0,3) += tRorQ*(-(s*s*y_t*y_t*a3)/((24.*pi*s*t+24.*pi*t*t)*s));
- highC(1,0) += tRorQ*(-1.0*(s*((s+t)*L_t - t*L_u)*y_t*y_t*a3)/(16.*pi*t*u*s));
- highC(1,1) += tRorQ*((s*L_t*y_t*y_t*a3)/(8.*pi*t*s));
- highC(1,2) += tRorQ*(-(s*s*y_t*y_t*a3)/((8.*pi*s*t+8.*pi*t*t)*s));
- highC(1,3) += tRorQ*(-(s*s*y_t*y_t*a3)/((8.*pi*s*t+8.*pi*t*t)*s));
- highC(2,0) += tRorQ*((s*((s+t)*L_t + t*L_u)*y_t*y_t*a3)/(16.*pi*t*u*s));
- highC(2,1) += tRorQ*(((2.*t-2.*t*L_s-s*L_t)*y_t*y_t*a3)/(8.*pi*t*s));
- highC(2,2) += tRorQ*(-1.0*(s*(s+2.*t)*y_t*y_t*a3)/(8.*pi*t*u*s));
- highC(2,3) += tRorQ*(-1.0*(s*(s+2.*t)*y_t*y_t*a3)/(8.*pi*t*u*s));
- }
- }
- break;
- default:
- assert(false);
- }
- return highC;
-}
-
-boost::numeric::ublas::matrix<complex<InvEnergy2> >
-HighEnergyMatching::Spin0HighMatching(Energy highScale,
- Energy2 s, Energy2 t, Energy2 u,
- EWProcess::Process process,
- bool oneLoop, bool ) {
- using Constants::pi;
- unsigned int order = !oneLoop? 0 : 1;
- // (If crossed graphs, swap s and t here)
- Complex L_s = MinusLog(-s/(highScale*highScale));
- Complex L_t = MinusLog(-t/(highScale*highScale));
- Complex L_u = MinusLog(-u/(highScale*highScale));
- Complex L_s2 = L_s*L_s;
- Complex L_t2 = L_t*L_t;
- Complex L_u2 = L_u*L_u;
-
- // Tree-Level:
- complex<InvEnergy2> S1 = 2.0/s;
-
- // Topology T1:
- complex<InvEnergy2> T1b = (-L_s2/(2.0*u)*(7.0*t/s+3.0)+2.0/u*L_t2+L_s*L_t*4.0/u*(t-u)/s+
- L_s*2.0/s-4.0/s-pi*pi/(4.0*u)*(11.0+19.0*t/s));
- complex<InvEnergy2> T1b_bar = -1.0*(-L_s2/(2.0*t)*(7.0*u/s+3.0)+2.0/t*L_u2+L_s*L_u*4.0/t*(u-t)/s+
- L_s*2.0/s-4.0/s-pi*pi/(4.0*t)*(11.0+19.0*u/s));
-
- // Topologies T2:
- complex<InvEnergy2> T2a = 1.0/s*(-2.0*L_s2+8.0*L_s-16.0+pi*pi/3.0);
- complex<InvEnergy2> T2b = 1.0/s*(0.5*L_s2+2.0*L_s-4.0-pi*pi/12.0);
-
- // Topologies T5:
- complex<InvEnergy2> T5a = 1.0/s*(-2.0*L_s2+6.0*L_s+pi*pi/3.0-16.0);
- complex<InvEnergy2> T5b = 1.0/s*(2.0*L_s-4.0);
-
- // Topologies T6:
- complex<InvEnergy2> T6a = 1.0/s*(-19.0/6.0*L_s+58.0/9.0);
- complex<InvEnergy2> T6b = 1.0/s*(-1.0/6.0*L_s+4.0/9.0);
- complex<InvEnergy2> T6c = 1.0/s*(2.0/3.0*L_s-16.0/9.0);
- complex<InvEnergy2> T6d = 1.0/s*(4.0/3.0*L_s-20.0/9.0);
-
- // Group Theory Factors / SM parameters needed for matrix elements:
- double a1 = ElectroWeakReweighter::coupling()->a1(highScale);
- double a2 = ElectroWeakReweighter::coupling()->a2(highScale);
- double a3 = ElectroWeakReweighter::coupling()->a3(highScale);
- double y_t = ElectroWeakReweighter::coupling()->y_t(highScale);
- double Y_phi = 1.0/2.0;
- double C_F_3 = 4.0/3.0;
- double C_F_2 = 3.0/4.0;
- double C_F_1 = 1.0;
- double n_g = 3.0;
- double n_S = 1.0;
- // Factors TBD after fermion helicity is specified:
- double Y_Q(0.), Lambda_Q(0.), Lambda_phi(0.);
- boost::numeric::ublas::matrix<complex<InvEnergy2> > highC(1,1);
- switch (process) {
-
- case QQPhiPhi: case LLPhiPhi:
- // Finish Group Theory Factors:
- if (process==QQPhiPhi) {
- Y_Q = 1.0/6.0;
- Lambda_Q = C_F_3*a3 + C_F_2*a2 + Y_Q*Y_Q*C_F_1*a1;
- Lambda_phi = C_F_2*a2+Y_phi*Y_phi*a1;
- }
- else if (process==LLPhiPhi) {
- Y_Q = -1.0/2.0;
- Lambda_Q = C_F_2*a2 + Y_Q*Y_Q*C_F_1*a1;
- Lambda_phi = C_F_2*a2+Y_phi*Y_phi*a1;
- }
- highC.resize(2,1);
- highC(0,0) = S1*(4.0*pi*a2);
- highC(1,0) = S1*(4.0*pi*a1*Y_Q*Y_phi);
- if (order>=1) {
- highC(0,0) += T1b*(0.5*a2*a2+2.0*a1*a2*Y_Q*Y_phi) +
- T1b_bar*(-0.5*a2*a2+2.0*a1*a2*Y_Q*Y_phi) +
- T2a*(-a2*a2+Lambda_phi*a2) + T2b*a2*a2 +
- T5a*(-a2*a2+Lambda_Q*a2) + T5b*a2*a2 +
- T6a*2.0*a2*a2 + T6b*2.0*a2*a2 +
- T6c*0.5*a2*a2*n_S + T6d*2.0*a2*a2*n_g;
- highC(1,0) += T1b*(3.0/16.0*a2*a2+a1*a1*Y_Q*Y_Q*Y_phi*Y_phi) +
- T1b_bar*(3.0/16.0*a2*a2+a1*a1*Y_Q*Y_Q*Y_phi*Y_phi) +
- T2a*(Lambda_phi*a1*Y_Q*Y_phi) + T5a*(Lambda_Q*a1*Y_Q*Y_phi) +
- T6c*(2.0*a1*a1*n_S*Y_Q*Y_phi*Y_phi*Y_phi) +
- T6d*(10.0/3.0*a1*a1*n_g*Y_Q*Y_phi);
- // Top Quark contributions:
- highC(0,0) += -3.0*y_t*y_t*a2/(4.0*pi)/s*(2.0*L_s-4.0);
- highC(1,0) += -3.0*y_t*y_t*a1/(4.0*pi)*(Y_Q*Y_phi)/s*(2.0*L_s-4.0);
- }
- break;
- case UUPhiPhi: case DDPhiPhi: case EEPhiPhi:
- // Finish Group Theory Factors:
- if (process==UUPhiPhi) {
- Y_Q = 2.0/3.0;
- Lambda_Q = C_F_3*a3 + Y_Q*Y_Q*C_F_1*a1;
- Lambda_phi = C_F_2*a2 + Y_phi*Y_phi*a1;
- }
- else if (process==DDPhiPhi) {
- Y_Q = -1.0/3.0;
- Lambda_Q = C_F_3*a3 + Y_Q*Y_Q*C_F_1*a1;
- Lambda_phi = C_F_2*a2 + Y_phi*Y_phi*a1;
- }
- else if (process==EEPhiPhi) {
- Y_Q = -1.0;
- Lambda_Q = Y_Q*Y_Q*C_F_1*a1;
- Lambda_phi = C_F_2*a2 + Y_phi*Y_phi*a1;
- }
-
- highC.resize(1,1);
- highC(0,0) = ZERO;
-
- highC(0,0) = S1*(4.0*pi*a1*Y_Q*Y_phi);
-
- if (order>=1) {
- highC(0,0) += T1b*(a1*a1*Y_Q*Y_Q*Y_phi*Y_phi) +
- T1b_bar*(a1*a1*Y_Q*Y_Q*Y_phi*Y_phi) +
- T2a*(Lambda_phi*a1*Y_Q*Y_phi) + T5a*(Lambda_Q*a1*Y_Q*Y_phi) +
- T6c*(2.0*a1*a1*n_S*Y_Q*Y_phi*Y_phi*Y_phi) +
- T6d*(10.0/3.0*a1*a1*n_g*Y_Q*Y_phi);
- // Top Quark Contribution:
- highC(0,0) += -3.0*y_t*y_t*a1/(4.0*pi)*(Y_Q*Y_phi)/s*(2.0*L_s-4.0);
- }
- break;
- default:
- assert(false);
- }
- return highC;
-}
diff --git a/MatrixElement/EW/HighEnergyMatching.h b/MatrixElement/EW/HighEnergyMatching.h
deleted file mode 100644
--- a/MatrixElement/EW/HighEnergyMatching.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// -*- C++ -*-
-//
-// HighEnergyMatching.h is a part of Herwig - A multi-purpose Monte Carlo event generator
-//
-// 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_HighEnergyMatching_H
-#define HERWIG_HighEnergyMatching_H
-#include "ThePEG/Config/ThePEG.h"
-#include "ThePEG/Config/Unitsystem.h"
-#include "EWProcess.h"
-// work around a Boost 1.64 bug where ublas headers would fail otherwise
-#include <boost/version.hpp>
-#if (BOOST_VERSION / 100 >= 1064)
-#include <boost/serialization/array_wrapper.hpp>
-#endif
-#include <boost/numeric/ublas/matrix.hpp>
-
-namespace Herwig {
-using namespace ThePEG;
-
-namespace HighEnergyMatching {
-
- /**
- * The high energy matching
- */
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- highEnergyMatching(Energy highScale,
- Energy2 s, Energy2 t, Energy2 u,
- Herwig::EWProcess::Process process,
- bool oneLoop, bool includeAlphaS2);
-
- /**
- * Spin\f$\frac12\f$
- */
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- SpinHalfMatching(Energy highScale,
- Energy2 s, Energy2 t, Energy2 u,
- EWProcess::Process process,
- bool oneLoop, bool includeAlphaS2);
-
- /**
- * Spin\f$1\f$
- */
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- Spin1HighMatching(Energy highScale,
- Energy2 s, Energy2 t, Energy2 u,
- EWProcess::Process process,
- bool oneLoop, bool includeAlphaS2);
- /**
- * Spin\f$0\f$
- */
- boost::numeric::ublas::matrix<complex<InvEnergy2> >
- Spin0HighMatching(Energy highScale,
- Energy2 s, Energy2 t, Energy2 u,
- EWProcess::Process process,
- bool oneLoop, bool includeAlphaS2);
-}
-}
-
-#endif // HERWIG_HighEnergyMatching_H
diff --git a/MatrixElement/EW/Makefile.am b/MatrixElement/EW/Makefile.am
deleted file mode 100644
--- a/MatrixElement/EW/Makefile.am
+++ /dev/null
@@ -1,10 +0,0 @@
-pkglib_LTLIBRARIES = HwMEEW.la
-HwMEEW_la_SOURCES = EWProcess.h GroupInvariants.h GroupInvariants.cc \
-ElectroWeakReweigter.h ElectroWeakReweighter.cc \
-SoftSudakov.h SoftSudakov.cc \
-CollinearSudakov.h CollinearSudakov.cc \
-HighEnergyMatching.h HighEnergyMatching.cc \
-ElectroWeakMatching.h ElectroWeakMatching.cc \
-EWCouplings.h EWCouplings.fh EWCouplings.cc \
-expm-1.hpp
-HwMEEW_la_LDFLAGS = $(AM_LDFLAGS) -module -version-info 1:0:0
diff --git a/MatrixElement/EW/SoftSudakov.cc b/MatrixElement/EW/SoftSudakov.cc
deleted file mode 100644
--- a/MatrixElement/EW/SoftSudakov.cc
+++ /dev/null
@@ -1,1321 +0,0 @@
-// -*- C++ -*-
-//
-// This is the implementation of the non-inlined, non-templated member
-// functions of the SoftSudakov class.
-//
-
-#include "SoftSudakov.h"
-#include "ThePEG/Interface/ClassDocumentation.h"
-#include "ThePEG/EventRecord/Particle.h"
-#include "ThePEG/Repository/UseRandom.h"
-#include "ThePEG/Repository/EventGenerator.h"
-#include "ThePEG/Utilities/DescribeClass.h"
-#include "GroupInvariants.h"
-#include "ThePEG/Persistency/PersistentOStream.h"
-#include "ThePEG/Persistency/PersistentIStream.h"
-#include "expm-1.h"
-
-using namespace Herwig;
-using namespace GroupInvariants;
-
-SoftSudakov::SoftSudakov() : K_ORDER_(3), integrator_(0.,1e-5,1000) {}
-
-SoftSudakov::~SoftSudakov() {}
-
-IBPtr SoftSudakov::clone() const {
- return new_ptr(*this);
-}
-
-IBPtr SoftSudakov::fullclone() const {
- return new_ptr(*this);
-}
-
-void SoftSudakov::persistentOutput(PersistentOStream & os) const {
- os << K_ORDER_;
-}
-
-void SoftSudakov::persistentInput(PersistentIStream & is, int) {
- is >> K_ORDER_;
-}
-
-
-// The following static variable is needed for the type
-// description system in ThePEG.
-DescribeClass<SoftSudakov,Interfaced>
-describeHerwigSoftSudakov("Herwig::SoftSudakov", "HwMEEW.so");
-
-void SoftSudakov::Init() {
-
- static ClassDocumentation<SoftSudakov> documentation
- ("The SoftSudakov class implements the soft EW Sudakov");
-
-}
-
-InvEnergy SoftSudakov::operator ()(Energy mu) const {
- // Include K-factor Contributions (Cusps):
- GaugeContributions cusp = cuspContributions(mu,K_ORDER_,high_);
- Complex gamma = cusp.SU3*G3_(row_,col_) + cusp.SU2*G2_(row_,col_) + cusp.U1*G1_(row_,col_);
- if (real_) {
- return gamma.real()/mu;
- }
- else {
- return gamma.imag()/mu;
- }
-}
-
-boost::numeric::ublas::matrix<Complex>
-SoftSudakov::evaluateSoft(boost::numeric::ublas::matrix<Complex> & G3,
- boost::numeric::ublas::matrix<Complex> & G2,
- boost::numeric::ublas::matrix<Complex> & G1,
- Energy mu_h, Energy mu_l, bool high) {
- assert( G3.size1() == G2.size1() && G3.size1() == G1.size1() &&
- G3.size2() == G2.size2() && G3.size2() == G1.size2() &&
- G3.size1() == G3.size2());
- G3_ = G3;
- G2_ = G2;
- G1_ = G1;
- high_ = high;
- unsigned int NN = G3_.size1();
- // gamma is the matrix to be numerically integrated to run the coefficients.
- boost::numeric::ublas::matrix<Complex> gamma(NN,NN);
- for(row_=0;row_<NN;++row_) {
- for(col_=0;col_<NN;++col_) {
- if(G3_(row_,col_) == 0. && G2_(row_,col_) == 0. && G1_(row_,col_) == 0.) {
- gamma(row_,col_) = 0.;
- }
- else {
- real_ = true;
- gamma(row_,col_).real(integrator_.value(*this,mu_h,mu_l));
- real_ = false;
- gamma(row_,col_).imag(integrator_.value(*this,mu_h,mu_l));
- }
- }
- }
- // Resummed:
- return boost::numeric::ublas::expm_pad(gamma,7);
-}
-
-boost::numeric::ublas::matrix<Complex>
-SoftSudakov::lowEnergyRunning(Energy EWScale, Energy lowScale,
- Energy2 s, Energy2 t, Energy2 u,
- Herwig::EWProcess::Process process,
- unsigned int iswap) {
- using namespace EWProcess;
- using namespace boost::numeric::ublas;
- using Constants::pi;
- static const Complex I(0,1.0);
- Complex T = getT(s,t), U = getU(s,u);
- matrix<Complex> G1, G2, G3;
- unsigned int numBrokenGauge;
- switch (process) {
- case QQQQ:
- case QQQQiden:
- case QtQtQQ:
- {
- numBrokenGauge = 12;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- matrix<Complex> gam3;
- if(iswap==0) {
- gam3 = Gamma3(U,T);
- G1(0,0) = G1(6,6) = Gamma1(2.0/3.0,2.0/3.0,2.0/3.0,2.0/3.0,T,U);
- G1(1,1) = G1(7,7) = Gamma1(-1.0/3.0,-1.0/3.0,2.0/3.0,2.0/3.0,T,U);
- G1(2,2) = G1(8,8) = Gamma1(2.0/3.0,2.0/3.0,-1.0/3.0,-1.0/3.0,T,U);
- G1(3,3) = G1(9,9) = Gamma1(-1.0/3.0,-1.0/3.0,-1.0/3.0,-1.0/3.0,T,U);
- G1(4,4) = G1(10,10) = Gamma1(-1.0/3.0,2.0/3.0,2.0/3.0,-1.0/3.0,T,U);
- G1(5,5) = G1(11,11) = Gamma1(2.0/3.0,-1.0/3.0,-1.0/3.0,2.0/3.0,T,U);
- }
- else if(iswap==1) {
- gam3 = Gamma3ST(U,T);
- G1(0,0) = G1(6,6) = Gamma1ST(2.0/3.0,2.0/3.0,2.0/3.0,2.0/3.0,T,U);
- G1(1,1) = G1(7,7) = Gamma1ST(-1.0/3.0,-1.0/3.0,2.0/3.0,2.0/3.0,T,U);
- G1(2,2) = G1(8,8) = Gamma1ST(2.0/3.0,2.0/3.0,-1.0/3.0,-1.0/3.0,T,U);
- G1(3,3) = G1(9,9) = Gamma1ST(-1.0/3.0,-1.0/3.0,-1.0/3.0,-1.0/3.0,T,U);
- G1(4,4) = G1(10,10) = Gamma1ST(-1.0/3.0,2.0/3.0,2.0/3.0,-1.0/3.0,T,U);
- G1(5,5) = G1(11,11) = Gamma1ST(2.0/3.0,-1.0/3.0,-1.0/3.0,2.0/3.0,T,U);
- }
- else if(iswap==2) {
- gam3 = Gamma3SU(U,T);
- G1(0,0) = G1(6,6) = Gamma1SU( 2.0/3.0,2.0/3.0,2.0/3.0,2.0/3.0,T,U);
- G1(1,1) = G1(7,7) = Gamma1SU(-1.0/3.0,-1.0/3.0,2.0/3.0,2.0/3.0,T,U);
- G1(2,2) = G1(8,8) = Gamma1SU( 2.0/3.0,2.0/3.0,-1.0/3.0,-1.0/3.0,T,U);
- G1(3,3) = G1(9,9) = Gamma1SU(-1.0/3.0,-1.0/3.0,-1.0/3.0,-1.0/3.0,T,U);
- G1(4,4) = G1(10,10) = Gamma1SU(-1.0/3.0,2.0/3.0,2.0/3.0,-1.0/3.0,T,U);
- G1(5,5) = G1(11,11) = Gamma1SU( 2.0/3.0,-1.0/3.0,-1.0/3.0,2.0/3.0,T,U);
- }
- else
- assert(false);
- for (unsigned int i=0; i<numBrokenGauge/2; i++) {
- G3(i,i) += gam3(0,0);
- G3(i,i+6) += gam3(0,1);
- G3(i+6,i) += gam3(1,0);
- G3(i+6,i+6) += gam3(1,1);
- }
- }
- break;
- case QQUU:
- case QtQtUU:
- case QQtRtR:
- {
- numBrokenGauge = 4;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- matrix<Complex> gam3;
- if(iswap==0) {
- gam3 = Gamma3(U,T);
- G1(0,0) = G1(2,2) = Gamma1(2.0/3.0,2.0/3.0,T,U);
- G1(1,1) = G1(3,3) = Gamma1(2.0/3.0,-1.0/3.0,T,U);
- }
- else if(iswap==1) {
- gam3 = Gamma3ST(U,T);
- G1(0,0) = G1(2,2) = Gamma1ST(2.0/3.0,2.0/3.0,T,U);
- G1(1,1) = G1(3,3) = Gamma1ST(2.0/3.0,-1.0/3.0,T,U);
- }
- else if(iswap==2) {
- gam3 = Gamma3SU(U,T);
- G1(0,0) = G1(2,2) = Gamma1SU(2.0/3.0,2.0/3.0,T,U);
- G1(1,1) = G1(3,3) = Gamma1SU(2.0/3.0,-1.0/3.0,T,U);
- }
- else
- assert(false);
-
- for (unsigned int i=0; i<numBrokenGauge/2; i++) {
- G3(i,i) += gam3(0,0);
- G3(i,i+2) += gam3(0,1);
- G3(i+2,i) += gam3(1,0);
- G3(i+2,i+2) += gam3(1,1);
- }
- }
- break;
- case QQDD:
- case QtQtDD:
- {
- numBrokenGauge = 4;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- matrix<Complex> gam3;
- if(iswap==0) {
- gam3 = Gamma3(U,T);
- G1(0,0) = G1(2,2) = Gamma1(-1.0/3.0,2.0/3.0,T,U);
- G1(1,1) = G1(3,3) = Gamma1(-1.0/3.0,-1.0/3.0,T,U);
- }
- else if(iswap==1) {
- gam3 = Gamma3ST(U,T);
- G1(0,0) = G1(2,2) = Gamma1ST(-1.0/3.0,2.0/3.0,T,U);
- G1(1,1) = G1(3,3) = Gamma1ST(-1.0/3.0,-1.0/3.0,T,U);
- }
- else if(iswap==2) {
- gam3 = Gamma3SU(U,T);
- G1(0,0) = G1(2,2) = Gamma1SU(-1.0/3.0,2.0/3.0,T,U);
- G1(1,1) = G1(3,3) = Gamma1SU(-1.0/3.0,-1.0/3.0,T,U);
- }
- else
- assert(false);
- for (unsigned int i=0; i<numBrokenGauge/2; i++) {
- G3(i,i) += gam3(0,0);
- G3(i,i+2) += gam3(0,1);
- G3(i+2,i) += gam3(1,0);
- G3(i+2,i+2) += gam3(1,1);
- }
- }
- break;
- case QQLL:
- {
- assert(iswap==0);
- numBrokenGauge = 6;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Complex gam3s = Gamma3Singlet()(0,0);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G3(i,i) = gam3s;
- }
- G1(0,0) = Gamma1(2.0/3.0,2.0/3.0,0.0,0.0,T,U);
- G1(1,1) = Gamma1(-1.0/3.0,-1.0/3.0,0.0,0.0,T,U);
- G1(2,2) = Gamma1(2.0/3.0,2.0/3.0,-1.0,-1.0,T,U);
- G1(3,3) = Gamma1(-1.0/3.0,-1.0/3.0,-1.0,-1.0,T,U);
- G1(4,4) = Gamma1(-1.0/3.0,2.0/3.0,0.0,-1.0,T,U);
- G1(5,5) = Gamma1(2.0/3.0,-1.0/3.0,-1.0,0.0,T,U);
- }
- break;
- case QQEE:
- {
- assert(iswap==0);
- numBrokenGauge = 2;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Complex gam3s = Gamma3Singlet()(0,0);
- for (unsigned int i=0; i<2; i++) {
- G3(i,i) += gam3s;
- }
- G1(0,0) = Gamma1(2.0/3.0,-1.0,T,U);
- G1(1,1) = Gamma1(-1.0/3.0,-1.0,T,U);
- }
- break;
- case UUUU:
- case UUUUiden:
- case tRtRUU:
- numBrokenGauge = 2;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- if(iswap==0) {
- G3 = Gamma3(U,T);
- G1(0,0) = G1(1,1) = Gamma1(2.0/3.0,2.0/3.0,T,U);
- }
- else if(iswap==1) {
- G3 = Gamma3ST(U,T);
- G1(0,0) = G1(1,1) = Gamma1ST(2.0/3.0,2.0/3.0,T,U);
- }
- else if(iswap==2) {
- G3 = Gamma3SU(U,T);
- G1(0,0) = G1(1,1) = Gamma1SU(2.0/3.0,2.0/3.0,T,U);
- }
- else
- assert(false);
- break;
- case UUDD:
- case tRtRDD:
- numBrokenGauge = 2;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- if(iswap==0) {
- G3 = Gamma3(U,T);
- G1(0,0) = G1(1,1) = Gamma1(-1.0/3.0,2.0/3.0,T,U);
- }
- else if(iswap==1) {
- G3 = Gamma3ST(U,T);
- G1(0,0) = G1(1,1) = Gamma1ST(-1.0/3.0,2.0/3.0,T,U);
- }
- else if(iswap==2) {
- G3 = Gamma3SU(U,T);
- G1(0,0) = G1(1,1) = Gamma1SU(-1.0/3.0,2.0/3.0,T,U);
- }
- else
- assert(false);
- break;
- case UULL:
- assert(iswap==0);
- numBrokenGauge = 2;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3(0,0) = G3(1,1) = Gamma3Singlet()(0,0);
- G1(0,0) = Gamma1(2.0/3.0,0.0,T,U);
- G1(1,1) = Gamma1(2.0/3.0,-1.0,T,U);
- break;
- case UUEE:
- assert(iswap==0);
- numBrokenGauge = 1;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3(0,0) = Gamma3Singlet()(0,0);
- G1(0,0) = Gamma1(2.0/3.0,-1.0,T,U);
- break;
- case DDDD:
- case DDDDiden:
- numBrokenGauge = 2;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- if(iswap==0) {
- G3 = Gamma3(U,T);
- G1(0,0) = G1(1,1) = Gamma1(-1.0/3.0,-1.0/3.0,T,U);
- }
- else if(iswap==1) {
- G3 = Gamma3ST(U,T);
- G1(0,0) = G1(1,1) = Gamma1ST(-1.0/3.0,-1.0/3.0,T,U);
- }
- else if(iswap==2) {
- G3 = Gamma3SU(U,T);
- G1(0,0) = G1(1,1) = Gamma1SU(-1.0/3.0,-1.0/3.0,T,U);
- }
- else
- assert(false);
- break;
- case DDLL:
- assert(iswap==0);
- numBrokenGauge = 2;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3(0,0) = G3(1,1) = Gamma3Singlet()(0,0);
- G1(0,0) = Gamma1(-1.0/3.0,0.0,T,U);
- G1(1,1) = Gamma1(-1.0/3.0,-1.0,T,U);
- break;
- case DDEE:
- assert(iswap==0);
- numBrokenGauge = 1;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3(0,0) = Gamma3Singlet()(0,0);
- G1(0,0) = Gamma1(-1.0/3.0,-1.0,T,U);
- break;
- case LLLL:
- case LLLLiden:
- assert(iswap==0);
- numBrokenGauge = 6;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G1(0,0) = Gamma1(0.0,0.0,0.0,0.0,T,U);
- G1(1,1) = Gamma1(-1.0,-1.0,0.0,0.0,T,U);
- G1(2,2) = Gamma1(0.0,0.0,-1.0,-1.0,T,U);
- G1(3,3) = Gamma1(-1.0,-1.0,-1.0,-1.0,T,U);
- G1(4,4) = Gamma1(-1.0,0.0,0.0,-1.0,T,U);
- G1(5,5) = Gamma1(0.0,-1.0,-1.0,0.0,T,U);
- break;
-
- case LLEE:
- assert(iswap==0);
- numBrokenGauge = 2;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G1(0,0) = Gamma1(0.0,-1.0,T,U);
- G1(1,1) = Gamma1(-1.0,-1.0,T,U);
- break;
- case EEEE:
- case EEEEiden:
- assert(iswap==0);
- numBrokenGauge = 1;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G1(0,0) = Gamma1(-1.0,-1.0,T,U);
- break;
- case QQWW:
- {
- assert(iswap==0);
- numBrokenGauge = 20;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Complex gam3s = Gamma3Singlet()(0,0);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G3(i,i) = gam3s;
- }
- G1(0,0) = Gamma1(2./3.,2./3.,-1.,-1.,T,U);
- G1(1,1) = Gamma1(2./3.,2./3.,1.,1.,T,U);
- G1(2,2) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(3,3) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(4,4) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(5,5) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(6,6) = Gamma1(-1./3.,-1./3.,-1.,-1.,T,U);
- G1(7,7) = Gamma1(-1./3.,-1./3.,1.,1.,T,U);
- G1(8,8) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- G1(9,9) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- G1(10,10) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- G1(11,11) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- G1(12,12) = Gamma1(-1./3.,2./3.,0.,-1.,T,U);
- G1(13,13) = Gamma1(-1./3.,2./3.,0.,-1.,T,U);
- G1(14,14) = Gamma1(-1./3.,2./3.,1.,0.,T,U);
- G1(15,15) = Gamma1(-1./3.,2./3.,1.,0.,T,U);
- G1(16,16) = Gamma1(2./3.,-1./3.,-1.,0.,T,U);
- G1(17,17) = Gamma1(2./3.,-1./3.,-1.,0.,T,U);
- G1(18,18) = Gamma1(2./3.,-1./3.,0.,1.,T,U);
- G1(19,19) = Gamma1(2./3.,-1./3.,0.,1.,T,U);
- }
- break;
- case QQPhiPhi:
- {
- assert(iswap==0);
- numBrokenGauge = 14;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Complex gam3s = Gamma3Singlet()(0,0);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G3(i,i) = gam3s;
- }
- G1(0,0) = Gamma1(2./3.,2./3.,1.,1.,T,U);
- G1(1,1) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(2,2) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(3,3) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(4,4) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(5,5) = Gamma1(-1./3.,-1./3.,1.,1.,T,U);
- G1(6,6) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- G1(7,7) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- G1(8,8) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- G1(9,9) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- G1(10,10) = Gamma1(-1./3.,2./3.,1.,0.,T,U);
- G1(11,11) = Gamma1(-1./3.,2./3.,1.,0.,T,U);
- G1(12,12) = Gamma1(2./3.,-1./3.,0.,1.,T,U);
- G1(13,13) = Gamma1(2./3.,-1./3.,0.,1.,T,U);
- }
- break;
- case QQWG:
- assert(iswap==0);
- numBrokenGauge = 6;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G3(i,i) = -17.0/6.0*I*pi + 3.0/2.0*(U+T);
- }
- G1(0,0) = Gamma1(-1./3.,2./3.,1.,0.,T,U);
- G1(1,1) = Gamma1(2./3.,-1./3.,-1.,0.,T,U);
- G1(2,2) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(3,3) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(4,4) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- G1(5,5) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- break;
- case QQBG:
- assert(iswap==0);
- numBrokenGauge = 4;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G3(i,i) = -4.0/3.0*I*pi + 3.0/2.0*(U+T-I*pi);
- }
- G1(0,0) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(1,1) = Gamma1(2./3.,2./3.,0.,0.,T,U);
- G1(2,2) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- G1(3,3) = Gamma1(-1./3.,-1./3.,0.,0.,T,U);
- break;
- case QQGG:
- case QtQtGG:
- {
- numBrokenGauge = 6;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- matrix<Complex> gam3g;
- Complex gam1a(0.),gam1b(0.);
- if(iswap==0) {
- gam3g = Gamma3g(U,T);
- gam1a = Gamma1( 2./3.,0.,T,U);
- gam1b = Gamma1(-1./3.,0.,T,U);
- }
- else if(iswap==1) {
- gam3g = Gamma3gST(U,T);
- gam1a = Gamma1ST( 2./3.,0.,T,U);
- gam1b = Gamma1ST(-1./3.,0.,T,U);
- }
- else if(iswap==2) {
- gam3g = Gamma3gSU(U,T);
- gam1a = Gamma1SU( 2./3.,0.,T,U);
- gam1b = Gamma1SU(-1./3.,0.,T,U);
- }
- else
- assert(false);
- for(unsigned int ix=0;ix<3;++ix) {
- for(unsigned int iy=0;iy<3;++iy) {
- G3(ix ,iy ) = gam3g(ix,iy);
- G3(ix+3,iy+3) = gam3g(ix,iy);
- }
- }
- G1(0,0) = G1(1,1) = G1(2,2) = gam1a;
- G1(3,3) = G1(4,4) = G1(5,5) = gam1b;
- }
- break;
- case LLWW:
- assert(iswap==0);
- numBrokenGauge = 20;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G1(0,0) = Gamma1(0.,0.,-1.,-1.,T,U);
- G1(1,1) = Gamma1(0.,0.,1.,1.,T,U);
- G1(2,2) = Gamma1(0.,0.,0.,0.,T,U);
- G1(3,3) = Gamma1(0.,0.,0.,0.,T,U);
- G1(4,4) = Gamma1(0.,0.,0.,0.,T,U);
- G1(5,5) = Gamma1(0.,0.,0.,0.,T,U);
- G1(6,6) = Gamma1(-1.,-1.,-1.,-1.,T,U);
- G1(7,7) = Gamma1(-1.,-1.,1.,1.,T,U);
- G1(8,8) = Gamma1(-1.,-1.,0.,0.,T,U);
- G1(9,9) = Gamma1(-1.,-1.,0.,0.,T,U);
- G1(10,10) = Gamma1(-1.,-1.,0.,0.,T,U);
- G1(11,11) = Gamma1(-1.,-1.,0.,0.,T,U);
- G1(12,12) = Gamma1(-1.,0.,0.,-1.,T,U);
- G1(13,13) = Gamma1(-1.,0.,0.,-1.,T,U);
- G1(14,14) = Gamma1(-1.,0.,1.,0.,T,U);
- G1(15,15) = Gamma1(-1.,0.,1.,0.,T,U);
- G1(16,16) = Gamma1(0.,-1.,-1.,0.,T,U);
- G1(17,17) = Gamma1(0.,-1.,-1.,0.,T,U);
- G1(18,18) = Gamma1(0.,-1.,0.,1.,T,U);
- G1(19,19) = Gamma1(0.,-1.,0.,1.,T,U);
- break;
- case LLPhiPhi:
- assert(iswap==0);
- numBrokenGauge = 14;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G1(0,0) = Gamma1(0.,0.,1.,1.,T,U);
- G1(1,1) = Gamma1(0.,0.,0.,0.,T,U);
- G1(2,2) = Gamma1(0.,0.,0.,0.,T,U);
- G1(3,3) = Gamma1(0.,0.,0.,0.,T,U);
- G1(4,4) = Gamma1(0.,0.,0.,0.,T,U);
- G1(5,5) = Gamma1(-1.,-1.,1.,1.,T,U);
- G1(6,6) = Gamma1(-1.,-1.,0.,0.,T,U);
- G1(7,7) = Gamma1(-1.,-1.,0.,0.,T,U);
- G1(8,8) = Gamma1(-1.,-1.,0.,0.,T,U);
- G1(9,9) = Gamma1(-1.,-1.,0.,0.,T,U);
- G1(10,10) = Gamma1(-1.,0.,1.,0.,T,U);
- G1(11,11) = Gamma1(-1.,0.,1.,0.,T,U);
- G1(12,12) = Gamma1(0.,-1.,0.,1.,T,U);
- G1(13,13) = Gamma1(0.,-1.,0.,1.,T,U);
- break;
- case UUBB:
- {
- assert(iswap==0);
- numBrokenGauge = 4;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Complex gam3s = Gamma3Singlet()(0,0);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G3(i,i) = gam3s;
- G1(i,i) = Gamma1(2./3.,0.,T,U);
- }
- }
- break;
- case UUPhiPhi:
- {
- assert(iswap==0);
- numBrokenGauge = 5;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Complex gam3s = Gamma3Singlet()(0,0);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G3(i,i) = gam3s;
- }
- G1(0,0) = Gamma1(2.0/3.0,2.0/3.0,1.,1.,T,U);
- G1(1,1) = G1(2,2) = G1(3,3) = G1(4,4) = Gamma1(2./3.,0.,T,U);
- }
- break;
- case UUBG:
- {
- assert(iswap==0);
- numBrokenGauge = 2;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Complex gam1 = Gamma1(2./3.,0.,T,U);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G3(i,i) = -4.0/3.0*I*pi + 3.0/2.0*(U+T-I*pi);
- G1(i,i) = gam1;
- }
- }
- break;
- case DDGG:
- case UUGG:
- case tRtRGG:
- {
- numBrokenGauge = 3;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Complex gam1(0.);
- double Y = process==DDGG ? -1./3. : 2./3.;
- if(iswap==0) {
- G3 = Gamma3g(U,T);
- gam1 = Gamma1(Y,0.,T,U);
- }
- else if(iswap==1) {
- G3 = Gamma3gST(U,T);
- gam1 = Gamma1ST(Y,0.,T,U);
- }
- else if(iswap==2) {
- G3 = Gamma3gSU(U,T);
- gam1 = Gamma1SU(Y,0.,T,U);
- }
- else
- assert(false);
- G1(0,0) = G1(1,1) = G1(2,2) = gam1;
- }
- break;
- case DDBB:
- {
- assert(iswap==0);
- numBrokenGauge = 4;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Complex gam3s = Gamma3Singlet()(0,0);
- Complex gam1 = Gamma1(-1./3.,0.,T,U);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G3(i,i) = gam3s;
- G1(i,i) = gam1;
- }
- }
- break;
- case DDPhiPhi:
- {
- assert(iswap==0);
- numBrokenGauge = 5;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Complex gam3s = Gamma3Singlet()(0,0);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G3(i,i) = gam3s;
- }
- G1(0,0) = Gamma1(-1.0/3.0,-1.0/3.0,1.,1.,T,U);
- G1(1,1) = G1(2,2) = G1(3,3) = G1(4,4) = Gamma1(-1./3.,0.,T,U);
- }
- break;
- case DDBG:
- assert(iswap==0);
- numBrokenGauge = 2;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G3(i,i) = -4.0/3.0*I*pi + 3.0/2.0*(U+T-I*pi);
- }
- G1(0,0) = G1(1,1) = Gamma1(-1./3.,0.,T,U);
- break;
- case EEBB:
- {
- assert(iswap==0);
- numBrokenGauge = 4;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- Complex gam1 = Gamma1(-1.,0.,T,U);
- for (unsigned int i=0; i<numBrokenGauge; i++) {
- G1(i,i) = gam1;
- };
- }
- break;
- case EEPhiPhi:
- assert(iswap==0);
- numBrokenGauge = 5;
- G1 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G2 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G3 = zero_matrix<Complex>(numBrokenGauge,numBrokenGauge);
- G1(0,0) = Gamma1(-1.,1.,T,U);
- G1(1,1) = G1(2,2) = G1(3,3) = G1(4,4) = Gamma1(-1.,0.,T,U);
- break;
- default:
- assert(false);
- }
- // return the answer
- if (EWScale==lowScale) {
- return identity_matrix<Complex>(G1.size1());
- }
- else {
- return evaluateSoft(G3,G2,G1,EWScale,lowScale,false);
- }
-}
-
-boost::numeric::ublas::matrix<Complex>
-SoftSudakov::highEnergyRunning(Energy highScale, Energy EWScale,
- Energy2 s, Energy2 t, Energy2 u,
- Herwig::EWProcess::Process process,
- unsigned int iswap) {
- using namespace EWProcess;
- using namespace boost::numeric::ublas;
- using Constants::pi;
- static const Complex I(0,1.0);
- Complex T = getT(s,t), U = getU(s,u);
- matrix<Complex> G1,G2,G3;
- unsigned int numGauge;
- switch (process) {
- case QQQQ:
- case QQQQiden:
- case QtQtQQ:
- {
- numGauge = 4;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- matrix<Complex> gam3,gam2;
- if(iswap==0) {
- gam3 = Gamma3(U,T);
- gam2 = Gamma2(U,T);
- G1(0,0) = G1(1,1) = G1(2,2) = G1(3,3) = Gamma1(1.0/6.0,1.0/6.0,T,U);
- }
- else if(iswap==1) {
- gam3 = Gamma3ST(U,T);
- gam2 = Gamma2ST(U,T);
- G1(0,0) = G1(1,1) = G1(2,2) = G1(3,3) = Gamma1ST(1.0/6.0,1.0/6.0,T,U);
- }
- else if(iswap==2) {
- gam3 = Gamma3SU(U,T);
- gam2 = Gamma2SU(U,T);
- G1(0,0) = G1(1,1) = G1(2,2) = G1(3,3) = Gamma1SU(1.0/6.0,1.0/6.0,T,U);
- }
- else
- assert(false);
- G3(0,0) += gam3(0,0);
- G3(0,2) += gam3(0,1);
- G3(2,0) += gam3(1,0);
- G3(2,2) += gam3(1,1);
- G3(1,1) += gam3(0,0);
- G3(1,3) += gam3(0,1);
- G3(3,1) += gam3(1,0);
- G3(3,3) += gam3(1,1);
- G2(0,0) += gam2(0,0);
- G2(0,1) += gam2(0,1);
- G2(1,0) += gam2(1,0);
- G2(1,1) += gam2(1,1);
- G2(2,2) += gam2(0,0);
- G2(2,3) += gam2(0,1);
- G2(3,2) += gam2(1,0);
- G2(3,3) += gam2(1,1);
- }
- break;
- case QQUU:
- case QtQtUU:
- case QQtRtR:
- numGauge = 2;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- if(iswap==0) {
- G3 = Gamma3(U,T);
- G2 = Gamma2Singlet();
- G1(0,0) = G1(1,1) = Gamma1(2.0/3.0,1.0/6.0,T,U);
- }
- else if(iswap==1) {
- G3 = Gamma3ST(U,T);
- G2 = Gamma2SingletST(T);
- G1(0,0) = G1(1,1) = Gamma1ST(2.0/3.0,1.0/6.0,T,U);
- }
- else if(iswap==2) {
- G3 = Gamma3SU(U,T);
- G2 = Gamma2SingletSU(U);
- G1(0,0) = G1(1,1) = Gamma1SU(2.0/3.0,1.0/6.0,T,U);
- }
- else
- assert(false);
- break;
- case QQDD:
- case QtQtDD:
- numGauge = 2;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- if(iswap==0) {
- G3 = Gamma3(U,T);
- G2 = Gamma2Singlet();
- G1(0,0) = G1(1,1) = Gamma1(-1.0/3.0,1.0/6.0,T,U);
- }
- else if(iswap==1) {
- G3 = Gamma3ST(U,T);
- G2 = Gamma2SingletST(T);
- G1(0,0) = G1(1,1) = Gamma1ST(-1.0/3.0,1.0/6.0,T,U);
- }
- else if(iswap==2) {
- G3 = Gamma3SU(U,T);
- G2 = Gamma2SingletSU(U);
- G1(0,0) = G1(1,1) = Gamma1SU(-1.0/3.0,1.0/6.0,T,U);
- }
- else
- assert(false);
- break;
- case QQLL:
- assert(iswap==0);
- numGauge = 2;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = Gamma3Singlet();
- G2 = Gamma2(U,T);
- G1(0,0) = G1(1,1) = Gamma1(-1.0/2.0,1.0/6.0,T,U);
- break;
- case QQEE:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = Gamma3Singlet()(0,0);
- G2(0,0) = Gamma2Singlet()(0,0);
- G1(0,0) = Gamma1(-1.0,1.0/6.0,T,U);
- break;
- case UUUU:
- case UUUUiden:
- case tRtRUU:
- numGauge = 2;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- if(iswap==0) {
- G3 = Gamma3(U,T);
- G1(0,0) = G1(1,1) = Gamma1(2.0/3.0,2.0/3.0,T,U);
- }
- else if(iswap==1) {
- G3 = Gamma3ST(U,T);
- G1(0,0) = G1(1,1) = Gamma1ST(2.0/3.0,2.0/3.0,T,U);
- }
- else if(iswap==2) {
- G3 = Gamma3SU(U,T);
- G1(0,0) = G1(1,1) = Gamma1SU(2.0/3.0,2.0/3.0,T,U);
- }
- else
- assert(false);
- break;
- case UUDD:
- case tRtRDD:
- numGauge = 2;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- if(iswap==0) {
- G3 = Gamma3(U,T);
- G1(0,0) = G1(1,1) = Gamma1(-1.0/3.0,2.0/3.0,T,U);
- }
- else if(iswap==1) {
- G3 = Gamma3ST(U,T);
- G1(0,0) = G1(1,1) = Gamma1ST(-1.0/3.0,2.0/3.0,T,U);
- }
- else if(iswap==2) {
- G3 = Gamma3SU(U,T);
- G1(0,0) = G1(1,1) = Gamma1SU(-1.0/3.0,2.0/3.0,T,U);
- }
- else
- assert(false);
- break;
- case UULL:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = Gamma3Singlet()(0,0);
- G2(0,0) = Gamma2Singlet()(0,0);
- G1(0,0) = Gamma1(-1.0/2.0,2.0/3.0,T,U);
- break;
- case UUEE:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = Gamma3Singlet()(0,0);
- G1(0,0) = Gamma1(-1.0,2.0/3.0,T,U);
- break;
- case DDDD:
- case DDDDiden:
- numGauge = 2;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- if(iswap==0) {
- G3 = Gamma3(U,T);
- G1(0,0) = G1(1,1) = Gamma1(-1.0/3.0,-1.0/3.0,T,U);
- }
- else if(iswap==1) {
- G3 = Gamma3ST(U,T);
- G1(0,0) = G1(1,1) = Gamma1ST(-1.0/3.0,-1.0/3.0,T,U);
- }
- else if(iswap==2) {
- G3 = Gamma3SU(U,T);
- G1(0,0) = G1(1,1) = Gamma1SU(-1.0/3.0,-1.0/3.0,T,U);
- }
- else
- assert(false);
- break;
- case DDLL:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = Gamma3Singlet()(0,0);
- G2(0,0) = Gamma2Singlet()(0,0);
- G1(0,0) = Gamma1(-1.0/2.0,-1.0/3.0,T,U);
- break;
- case DDEE:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = Gamma3Singlet()(0,0);
- G1(0,0) = Gamma1(-1.0,-1.0/3.0,T,U);
- break;
- case LLLL:
- case LLLLiden:
- assert(iswap==0);
- numGauge = 2;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = Gamma2(U,T);
- G1(0,0) = G1(1,1) = Gamma1(-1.0/2.0,-1.0/2.0,T,U);
- break;
- case LLEE:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G2(0,0) = Gamma2Singlet()(0,0);
- G1(0,0) = Gamma1(-1.0,-1.0/2.0,T,U);
- break;
- case EEEE:
- case EEEEiden:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G1(0,0) = Gamma1(-1.0,-1.0,T,U);
- break;
- case QQWW:
- {
- assert(iswap==0);
- numGauge = 5;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- Complex gam3s = Gamma3Singlet()(0,0);
- for (unsigned int i=0; i<5; i++) {
- G3(i,i) = gam3s;
- G1(i,i) = Gamma1(1.0/6.0);
- }
- G2 = Gamma2w(U,T);
- }
- break;
- case QQPhiPhi:
- assert(iswap==0);
- numGauge = 2;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = Gamma3Singlet();
- G2 = Gamma2(U,T);
- G1(0,0) = G1(1,1) = Gamma1(1.0/2.0,1.0/6.0,T,U);
- break;
- case QQWG:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = -17.0/6.0*I*pi + 3.0/2.0*(U+T);
- G2(0,0) = -7.0/4.0*I*pi + (U+T);
- G1(0,0) = Gamma1(1.0/6.0);
- break;
- case QQBG:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = -4.0/3.0*I*pi + 3.0/2.0*(U+T-I*pi);
- G2(0,0) = -3.0/4.0*I*pi;
- G1(0,0) = Gamma1(1.0/6.0);
- break;
- case QQGG:
- case QtQtGG:
- {
- numGauge = 3;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- Complex gam2s,gam1;
- if(iswap==0) {
- G3 = Gamma3g(U,T);
- gam2s = Gamma2Singlet()(0,0);
- gam1 = Gamma1(1.0/6.0);
- }
- else if(iswap==1) {
- G3 = Gamma3gST(U,T);
- gam2s = Gamma2SingletST(T)(0,0);
- gam1 = Gamma1ST(1.0/6.0,T);
- }
- else if(iswap==2) {
- G3 = Gamma3gSU(U,T);
- gam2s = Gamma2SingletSU(U)(0,0);
- gam1 = Gamma1SU(1.0/6.0,U);
- }
- else
- assert(false);
- for (unsigned int i=0; i<3; i++) {
- G2(i,i) = gam2s;
- G1(i,i) = gam1;
- }
- }
- break;
- case LLWW:
- assert(iswap==0);
- numGauge = 5;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- for (unsigned int i=0; i<5; i++) {
- G1(i,i) = Gamma1(-1.0/2.0);
- }
- G2 = Gamma2w(U,T);
- break;
- case LLPhiPhi:
- assert(iswap==0);
- numGauge = 2;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = Gamma2(U,T);
- G1(0,0) = G1(1,1) = Gamma1(1.0/2.0,-1.0/2.0,T,U);
- break;
- case UUBB:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = Gamma3Singlet()(0,0);
- G1(0,0) = Gamma1(2.0/3.0);
- break;
- case UUPhiPhi:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = Gamma3Singlet()(0,0);
- G2(0,0) = Gamma2Singlet()(0,0);
- G1(0,0) = Gamma1(1.0/2.0,2.0/3.0,T,U);
- break;
- case UUBG:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = -4.0/3.0*I*pi + 3.0/2.0*(U+T-I*pi);
- G1(0,0) = Gamma1(2.0/3.0);
- break;
- case DDGG:
- case UUGG:
- case tRtRGG:
- {
- numGauge = 3;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- double Y = process==DDGG ? -1./3. : 2./3.;
- Complex gam1(0.);
- if(iswap==0) {
- G3 = Gamma3g(U,T);
- gam1 = Gamma1(Y);
- }
- else if(iswap==1) {
- G3 = Gamma3gST(U,T);
- gam1 = Gamma1ST(Y,T);
- }
- else if(iswap==2) {
- G3 = Gamma3gSU(U,T);
- gam1 = Gamma1SU(Y,U);
- }
- else
- assert(false);
- for (unsigned int i=0; i<3; i++) {
- G1(i,i) = gam1;
- }
- }
- break;
- case DDBB:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = Gamma3Singlet()(0,0);
- G1(0,0) = Gamma1(-1.0/3.0);
- break;
- case DDPhiPhi:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = Gamma3Singlet()(0,0);
- G2(0,0) = Gamma2Singlet()(0,0);
- G1(0,0) = Gamma1(1.0/2.0,-1.0/3.0,T,U);
- break;
- case DDBG:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G3(0,0) = -4.0/3.0*I*pi + 3.0/2.0*(U+T-I*pi);
- G1(0,0) = Gamma1(-1.0/3.0);
- break;
- case EEBB:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G1(0,0) = Gamma1(-1.0);
- break;
- case EEPhiPhi:
- assert(iswap==0);
- numGauge = 1;
- G1 = zero_matrix<Complex>(numGauge,numGauge);
- G2 = zero_matrix<Complex>(numGauge,numGauge);
- G3 = zero_matrix<Complex>(numGauge,numGauge);
- G2(0,0) = Gamma2Singlet()(0,0);
- G1(0,0) = Gamma1(1.0/2.0,-1.0,T,U);
- break;
- default:
- assert(false);
- }
- return evaluateSoft(G3,G2,G1,highScale,EWScale,true);
-}
-
-unsigned int SoftSudakov::numberGauge(Herwig::EWProcess::Process process) {
- using namespace EWProcess;
- switch (process) {
- case QQQQ:
- case QQQQiden:
- case QtQtQQ:
- return 4;
- case QQUU:
- case QtQtUU:
- case QQtRtR:
- return 2;
- case QQDD:
- case QtQtDD:
- return 2;
- case QQLL:
- return 2;
- case QQEE:
- return 1;
- case UUUU:
- case UUUUiden:
- case tRtRUU:
- return 2;
- case UUDD:
- case tRtRDD:
- return 2;
- case UULL:
- return 1;
- case UUEE:
- return 1;
- case DDDD:
- case DDDDiden:
- return 2;
- case DDLL:
- return 1;
- case DDEE:
- return 1;
- case LLLL:
- case LLLLiden:
- return 2;
- case LLEE:
- return 1;
- case EEEE:
- case EEEEiden:
- return 1;
- case QQWW:
- return 5;
- case QQPhiPhi:
- return 2;
- case QQWG:
- return 1;
- case QQBG:
- return 1;
- case QQGG:
- case QtQtGG:
- return 3;
- case LLWW:
- return 5;
- case LLPhiPhi:
- return 2;
- case UUBB:
- return 1;
- case UUPhiPhi:
- return 1;
- case UUBG:
- return 1;
- case UUGG:
- case tRtRGG:
- return 3;
- case DDBB:
- return 1;
- case DDPhiPhi:
- return 1;
- case DDBG:
- return 1;
- case DDGG:
- return 3;
- case EEBB:
- return 1;
- case EEPhiPhi:
- return 1;
- default:
- assert(false);
- }
-}
-
-unsigned int SoftSudakov::numberBrokenGauge(Herwig::EWProcess::Process process) {
- using namespace EWProcess;
- switch (process) {
- case QQQQ:
- case QQQQiden:
- case QtQtQQ:
- return 12;
- case QQUU:
- case QtQtUU:
- case QQtRtR:
- return 4;
- case QQDD:
- case QtQtDD:
- return 4;
- case QQLL:
- return 6;
- case QQEE:
- return 2;
- case UUUU:
- case UUUUiden:
- case tRtRUU:
- return 2;
- case UUDD:
- case tRtRDD:
- return 2;
- case UULL:
- return 2;
- case UUEE:
- return 1;
- case DDDD:
- case DDDDiden:
- return 2;
- case DDLL:
- return 2;
- case DDEE:
- return 1;
- case LLLL:
- case LLLLiden:
- return 6;
- case EEEE:
- case EEEEiden:
- return 1;
- case QQWW:
- return 20;
- case QQPhiPhi:
- return 14;
- case QQWG:
- return 6;
- case QQBG:
- return 4;
- case QQGG:
- case QtQtGG:
- return 6;
- case LLWW:
- return 20;
- case LLPhiPhi:
- return 14;
- case UUBB:
- return 4;
- case UUPhiPhi:
- return 5;
- case UUBG:
- return 2;
- case UUGG:
- case tRtRGG:
- return 3;
- case DDBB:
- return 4;
- case DDPhiPhi:
- return 5;
- case DDBG:
- return 2;
- case DDGG:
- return 3;
- case EEBB:
- return 4;
- case EEPhiPhi:
- return 5;
- default:
- assert(false);
- }
-}
diff --git a/MatrixElement/EW/SoftSudakov.fh b/MatrixElement/EW/SoftSudakov.fh
deleted file mode 100644
--- a/MatrixElement/EW/SoftSudakov.fh
+++ /dev/null
@@ -1,18 +0,0 @@
-// -*- C++ -*-
-//
-// This is the forward declaration of the SoftSudakov class.
-//
-#ifndef Herwig_SoftSudakov_FH
-#define Herwig_SoftSudakov_FH
-
-#include "ThePEG/Config/ThePEG.h"
-
-namespace Herwig {
-
-class SoftSudakov;
-
-ThePEG_DECLARE_POINTERS(Herwig::SoftSudakov,SoftSudakovPtr);
-
-}
-
-#endif
diff --git a/MatrixElement/EW/SoftSudakov.h b/MatrixElement/EW/SoftSudakov.h
deleted file mode 100644
--- a/MatrixElement/EW/SoftSudakov.h
+++ /dev/null
@@ -1,198 +0,0 @@
-// -*- C++ -*-
-#ifndef Herwig_SoftSudakov_H
-#define Herwig_SoftSudakov_H
-//
-// This is the declaration of the SoftSudakov class.
-//
-
-#include "ThePEG/Interface/Interfaced.h"
-#include "Herwig/Utilities/GSLIntegrator.h"
-// work around a Boost 1.64 bug where ublas headers would fail otherwise
-#include <boost/version.hpp>
-#if (BOOST_VERSION / 100 >= 1064)
-#include <boost/serialization/array_wrapper.hpp>
-#endif
-#include <boost/numeric/ublas/matrix.hpp>
-#include "EWProcess.h"
-#include "SoftSudakov.fh"
-
-namespace Herwig {
-
-using namespace ThePEG;
-
-/**
- * Here is the documentation of the SoftSudakov class.
- *
- * @see \ref SoftSudakovInterfaces "The interfaces"
- * defined for SoftSudakov.
- */
-class SoftSudakov: public Interfaced {
-
-public:
-
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- SoftSudakov();
-
- /**
- * The destructor.
- */
- virtual ~SoftSudakov();
- //@}
-
-public:
-
- /**
- * Low energy soft evolution
- */
- boost::numeric::ublas::matrix<Complex>
- lowEnergyRunning(Energy EWScale, Energy lowScale,
- Energy2 s, Energy2 t, Energy2 u,
- Herwig::EWProcess::Process process,
- unsigned int iswap);
-
- /**
- * Evalaute the high energy running as a matrix
- */
- boost::numeric::ublas::matrix<Complex>
- highEnergyRunning(Energy highScale, Energy EWScale,
- Energy2 s, Energy2 t, Energy2 u,
- Herwig::EWProcess::Process process,
- unsigned int iswap);
-
- /**
- * Number of operators for the broken theory at low energy
- */
- unsigned int numberBrokenGauge(Herwig::EWProcess::Process process);
-
- /**
- * Number of operators for the unbroken theory at high energy
- */
- unsigned int numberGauge(Herwig::EWProcess::Process process);
-
-protected:
-
- /**
- * Evaluate the soft evolution
- */
- boost::numeric::ublas::matrix<Complex> evaluateSoft(boost::numeric::ublas::matrix<Complex> & G3,
- boost::numeric::ublas::matrix<Complex> & G2,
- boost::numeric::ublas::matrix<Complex> & G1,
- Energy mu_h, Energy mu_l, bool high);
-
-public:
-
- /**
- * The operator to be integrated
- */
- InvEnergy operator ()(Energy mu) const;
- /** Argument type for GaussianIntegrator */
- typedef Energy ArgType;
- /** Return type for GaussianIntegrator */
- typedef InvEnergy ValType;
-
-public:
-
- /** @name Functions used by the persistent I/O system. */
- //@{
- /**
- * Function used to write out object persistently.
- * @param os the persistent output stream written to.
- */
- void persistentOutput(PersistentOStream & os) const;
-
- /**
- * Function used to read in object persistently.
- * @param is the persistent input stream read from.
- * @param version the version number of the object when written.
- */
- void persistentInput(PersistentIStream & is, int version);
- //@}
-
- /**
- * The standard Init function used to initialize the interfaces.
- * Called exactly once for each class by the class description system
- * before the main function starts or
- * when this class is dynamically loaded.
- */
- static void Init();
-
-protected:
-
- /** @name Clone Methods. */
- //@{
- /**
- * Make a simple clone of this object.
- * @return a pointer to the new object.
- */
- virtual IBPtr clone() const;
-
- /** Make a clone of this object, possibly modifying the cloned object
- * to make it sane.
- * @return a pointer to the new object.
- */
- virtual IBPtr fullclone() const;
- //@}
-
-private:
-
- /**
- * The assignment operator is private and must never be called.
- * In fact, it should not even be implemented.
- */
- SoftSudakov & operator=(const SoftSudakov &) = delete;
-
-private:
-
- /**
- * Order for K
- */
- unsigned int K_ORDER_;
-
- /**
- * Integrator
- */
- GSLIntegrator integrator_;
-
- /**
- * Whether doing the high or low scale contribution
- */
- bool high_;
-
- /**
- * Column
- */
- unsigned int row_;
-
- /**
- * Row
- */
- unsigned int col_;
-
- /**
- *
- */
- bool real_;
-
- /**
- *
- */
- boost::numeric::ublas::matrix<Complex> G1_;
-
- /**
- *
- */
- boost::numeric::ublas::matrix<Complex> G2_;
-
- /**
- *
- */
- boost::numeric::ublas::matrix<Complex> G3_;
-};
-
-}
-
-#endif /* Herwig_SoftSudakov_H */
diff --git a/MatrixElement/EW/expm-1.h b/MatrixElement/EW/expm-1.h
deleted file mode 100644
--- a/MatrixElement/EW/expm-1.h
+++ /dev/null
@@ -1,148 +0,0 @@
-//
-// Copyright (c) 2007
-// Tsai, Dung-Bang
-// National Taiwan University, Department of Physics
-//
-// E-Mail : dbtsai (at) gmail.com
-// Begine : 2007/11/20
-// Last modify : 2007/11/22
-// Version : v0.1
-//
-// EXPGM_PAD computes the matrix exponential exp(H) for general matrixs,
-// including complex and real matrixs using the irreducible (p,p) degree
-// rational Pade approximation to the exponential
-// exp(z) = r(z)=(+/-)( I+2*(Q(z)/P(z))).
-//
-// Usage :
-//
-// U = expm_pad(H)
-// U = expm_pad(H, p)
-//
-// where p is internally set to 6 (recommended and gererally satisfactory).
-//
-// See also MATLAB supplied functions, EXPM and EXPM1.
-//
-// Reference :
-// EXPOKIT, Software Package for Computing Matrix Exponentials.
-// ACM - Transactions On Mathematical Software, 24(1):130-156, 1998
-//
-// Permission to use, copy, modify, distribute and sell this software
-// and its documentation for any purpose is hereby granted without fee,
-// provided that the above copyright notice appear in all copies and
-// that both that copyright notice and this permission notice appear
-// in supporting documentation. The authors make no representations
-// about the suitability of this software for any purpose.
-// It is provided "as is" without express or implied warranty.
-//
-
-#ifndef _BOOST_UBLAS_EXPM_
-#define _BOOST_UBLAS_EXPM_
-#include <boost/throw_exception.hpp>
-#include <complex>
-#include <boost/numeric/ublas/vector.hpp>
-#include <boost/numeric/ublas/matrix.hpp>
-#include <boost/numeric/ublas/lu.hpp>
-
-namespace boost { namespace numeric { namespace ublas {
-
-template<typename MATRIX> MATRIX expm_pad(const MATRIX &H, const int p = 6) {
- typedef typename MATRIX::value_type value_type;
- typedef typename MATRIX::size_type size_type;
- typedef double real_value_type; // Correct me. Need to modify.
- assert(H.size1() == H.size2());
- const size_type n = H.size1();
- const identity_matrix<value_type> I(n);
- matrix<value_type> U(n,n),H2(n,n),P(n,n),Q(n,n);
- real_value_type norm = 0.0;
-
- // Calcuate Pade coefficients (1-based instead of 0-based as in the c vector)
- vector<real_value_type> c(p+2);
- c(1)=1;
- for(size_type i = 1; i <= p; ++i)
- c(i+1) = c(i) * ((p + 1.0 - i)/(i * (2.0 * p + 1 - i)));
- // Calcuate the infinty norm of H, which is defined as the largest row sum of a matrix
- for(size_type i=0; i<n; ++i)
- {
- real_value_type temp = 0.0;
- for(size_type j=0;j<n;j++)
- temp += std::abs<real_value_type>(H(j,i)); // Correct me, if H is complex, can I use that abs?
- norm = std::max<real_value_type>(norm, temp);
- }
- if (norm == 0.0)
- {
- boost::throw_exception(boost::numeric::ublas::bad_argument());
- std::cerr<<"Error! Null input in the routine EXPM_PAD.\n";
- exit(0);
- }
- // Scaling, seek s such that || H*2^(-s) || < 1/2, and set scale = 2^(-s)
- int s = 0;
- real_value_type scale = 1.0;
- if(norm > 0.5) {
- s = std::max<int>(0, static_cast<int>((log(norm) / log(2.0) + 2.0)));
- scale /= static_cast<real_value_type>(std::pow(2.0, s));
- U.assign(scale * H); // Here U is used as temp value due to that H is const
- }
- else
- U.assign(H);
- // Horner evaluation of the irreducible fraction, see the following ref above.
- // Initialise P (numerator) and Q (denominator)
- H2.assign( prod(U, U) );
- Q.assign( c(p+1)*I );
- P.assign( c(p)*I );
- size_type odd = 1;
- for( size_type k = p - 1; k > 0; --k)
- {
- if( odd == 1)
- {
- Q = ( prod(Q, H2) + c(k) * I );
- }
- else
- {
- P = ( prod(P, H2) + c(k) * I );
- }
- odd = 1 - odd;
- }
- if( odd == 1)
- {
- Q = ( prod(Q, U) );
- Q -= P ;
- //U.assign( -(I + 2*(Q\P)));
- }
- else
- {
- P = (prod(P, U));
- Q -= P;
- //U.assign( I + 2*(Q\P));
- }
- // In origine expokit package, they use lapack ZGESV to obtain inverse matrix,
- // and in that ZGESV routine, it uses LU decomposition for obtaing inverse matrix.
- // Since in ublas, there is no matrix inversion template, I simply use the build-in
- // LU decompostion package in ublas, and back substitute by myself.
- //
- //////////////// Implement Matrix Inversion ///////////////////////
- permutation_matrix<size_type> pm(n);
- int res = lu_factorize(Q, pm);
- if( res != 0)
- {
- std::cerr << "Error in the matrix inversion in template expm_pad.\n";
- exit(0);
- }
- H2 = I; // H2 is not needed anymore, so it is temporary used as identity matrix for substituting.
-
- lu_substitute(Q, pm, H2);
- if( odd == 1)
- U.assign( -(I + 2.0 * prod(H2, P)));
- else
- U.assign( I + 2.0 * prod(H2, P));
- // Squaring
- for(size_t i = 0; i < s; ++i)
- {
- U = (prod(U,U));
- }
- return U;
- }
-
-}}}
-
-
-#endif
diff --git a/MatrixElement/FxFx/FxFxEventHandler.cc b/MatrixElement/FxFx/FxFxEventHandler.cc
--- a/MatrixElement/FxFx/FxFxEventHandler.cc
+++ b/MatrixElement/FxFx/FxFxEventHandler.cc
@@ -1,673 +1,671 @@
// -*- C++ -*-
//
// Based on:
// FxFxEventHandler.cc is a part of ThePEG - Toolkit for HEP Event Generation
// Copyright (C) 1999-2019 Leif Lonnblad
//
// ThePEG is licenced under version 3 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 FxFxEventHandler class.
//
#include "FxFxEventHandler.h"
#include "FxFxReader.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Repository/Repository.h"
#include "ThePEG/Handlers/LuminosityFunction.h"
#include "ThePEG/Handlers/XComb.h"
#include "ThePEG/Handlers/CascadeHandler.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/PDF/PartonExtractor.h"
#include "ThePEG/Utilities/LoopGuard.h"
#include "ThePEG/EventRecord/Event.h"
#include "ThePEG/EventRecord/Collision.h"
#include "ThePEG/EventRecord/Step.h"
#include "ThePEG/EventRecord/SubProcess.h"
#include "ThePEG/Utilities/EnumIO.h"
#include "ThePEG/Utilities/Maths.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Utilities/Throw.h"
#include "ThePEG/Utilities/Debug.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace ThePEG;
-FxFxEventHandler::~FxFxEventHandler() {}
-
IBPtr FxFxEventHandler::clone() const {
return new_ptr(*this);
}
IBPtr FxFxEventHandler::fullclone() const {
return new_ptr(*this);
}
void FxFxEventHandler::doinit() {
EventHandler::doinit();
for ( int i = 0, N = readers().size(); i < N; ++i ) {
readers()[i]->init();
//FxFxReader & reader = *readers()[i];
//reader.initialize(*this);
//weightnames = reader.optWeightsNamesFunc();
}
/*
XSecStat* initxsecs = new XSecStat[weightnames.size()];
for(int ww = 0; ww < weightnames.size(); ww++){
initxsecs[ww].reset();
optstats.insert(std::make_pair<string,XSecStat>(weightnames[ww], initxsecs[ww]));
opthistStats.insert(std::make_pair<string,XSecStat>(weightnames[ww], initxsecs[ww]));
CrossSection initxs = 0.*picobarn;
optxs.insert(std::make_pair<string,CrossSection>(weightnames[ww], initxs));
}*/
ntries = 0;
}
void FxFxEventHandler::initialize() {
if ( lumiFnPtr() ) Repository::clog()
<< "The LuminosityFunction '" << lumiFnPtr()->name()
<< "' assigned to the FxFxEventHandler '" << name()
<< "' will not be active in this run. Instead the incoming "
<< "particles will be determined by the used FxFxReader objects.\n"
<< Exception::warning;
if ( readers().empty() )
throw FxFxInitError()
<< "No readers were defined for the FxFxEventHandler '"
<< name() << "'" << Exception::warning;
// Go through all the readers and collect information about cross
// sections and processes.
typedef map<int,tFxFxReaderPtr> ProcessMap;
ProcessMap processes;
PDPair incoming;
Energy MaxEA = ZERO;
Energy MaxEB = ZERO;
for ( int i = 0, N = readers().size(); i < N; ++i ) {
FxFxReader & reader = *readers()[i];
reader.initialize(*this);
weightnames = reader.optWeightsNamesFunc();
// Check that the incoming particles are consistent between the
// readers.
if ( !incoming.first ) {
incoming.first = getParticleData(reader.heprup.IDBMUP.first);
if ( !incoming.first )
Throw<FxFxInitError>()
<< "Unknown beam PID " << reader.heprup.IDBMUP.first
<< ". Have you created a matching BeamParticle object?"
<< Exception::runerror;
}
if ( !incoming.second ) {
incoming.second = getParticleData(reader.heprup.IDBMUP.second);
if ( !incoming.second )
Throw<FxFxInitError>()
<< "Unknown beam PID " << reader.heprup.IDBMUP.first
<< ". Have you created a matching BeamParticle object?"
<< Exception::runerror;
}
if ( incoming.first->id() != reader.heprup.IDBMUP.first ||
incoming.second->id() != reader.heprup.IDBMUP.second )
Repository::clog()
<< "The different FxFxReader objects in the "
<< "FxFxEventHandler '" << name() << "' have different "
<< "types of colliding particles." << Exception::warning;
MaxEA = max(MaxEA, reader.heprup.EBMUP.first*GeV);
MaxEB = max(MaxEB, reader.heprup.EBMUP.second*GeV);
// Check that the weighting of the events in the different readers
// is consistent with the ones requested for this event
// handler. Also collect the sum of the maximum weights.
if ( reader.negativeWeights() && weightOption() > 0 )
throw FxFxInitError()
<< "The reader '" << reader.name()
<< "' contains negatively weighted events, "
<< "which is not allowed for the FxFxEventHandler '"
<< name() << "'." << Exception::warning;
// Check that we do not have the same process numbers in different
// readers.
for ( int ip = 0; ip < reader.heprup.NPRUP; ++ip ) {
if ( reader.heprup.LPRUP[ip] ) {
ProcessMap::iterator pit = processes.find(reader.heprup.LPRUP[ip]);
if ( pit == processes.end() )
processes[reader.heprup.LPRUP[ip]] = readers()[i];
else if ( warnPNum ) {
Throw<FxFxPNumException>()
<< "In the FxFxEventHandler '"
<< name() << "', both the '" << pit->second->name() << "' and '"
<< reader.name() << "' contains sub-process number " << pit->first
<< ". This process may be double-counted in this run."
<< Exception::warning;
}
}
}
selector().insert(reader.stats.maxXSec(), i);
}
stats.maxXSec(selector().sum());
histStats.maxXSec(selector().sum());
for (map<string,XSecStat>::iterator it= optstats.begin(); it!=optstats.end(); ++it){
(it->second).maxXSec(selector().sum());
}
// Check that we have any cross section at all.
if ( stats.maxXSec() <= ZERO )
throw FxFxInitError()
<< "The sum of the cross sections of the readers in the "
<< "FxFxEventHandler '" << name()
<< "' was zero." << Exception::warning;
// We now create a LuminosityFunction object to inform others about
// the energy of the beam.
theIncoming = incoming;
lumiFn(new_ptr(LuminosityFunction(MaxEA, MaxEB)));
}
void FxFxEventHandler::doinitrun() {
EventHandler::doinitrun();
stats.reset();
histStats.reset();
for ( int i = 0, N = readers().size(); i < N; ++i ) {
readers()[i]->init();
FxFxReader & reader = *readers()[i];
reader.initialize(*this);
weightnames = reader.optWeightsNamesFunc();
}
// XSecStat initxsecs;
XSecStat* initxsecs = new XSecStat[weightnames.size()];
for(size_t ww = 0; ww < weightnames.size(); ww++){
initxsecs[ww].reset();
// optstats.insert(std::make_pair<string,XSecStat>(weightnames[ww], initxsecs[ww]));
// opthistStats.insert(std::make_pair<string,XSecStat>(weightnames[ww], initxsecs[ww]));
CrossSection initxs = 0.*picobarn;
//optxs.insert(std::make_pair<string,CrossSection>(weightnames[ww], initxs));
optstats.insert(std::make_pair(weightnames[ww], initxsecs[ww]));
opthistStats.insert(std::make_pair(weightnames[ww], initxsecs[ww]));
optxs.insert(std::make_pair(weightnames[ww], initxs));
}
ntries = 0;
}
EventPtr FxFxEventHandler::generateEvent() {
LoopGuard<EventLoopException,FxFxEventHandler>
loopGuard(*this, maxLoop());
while ( true ) {
loopGuard();
currentReader(readers()[selector().select(UseRandom::current())]);
skipEvents();
currentReader()->reset();
double weight = currentReader()->getEvent();
if ( weightOption() == unitweight && weight < 0.0 ) weight = 0.0;
if ( weightOption() == unitweight || weightOption() == unitnegweight ) {
CrossSection newmax = selector().reweight(weight);
if ( newmax > CrossSection() )
increaseMaxXSec(newmax);
}
select(weight/currentReader()->preweight);
histStats.select(weight);
if ( !weighted() ) {
if ( weightOption() == unitweight || weightOption() == unitnegweight ) {
if ( !rndbool(abs(weight)) ) continue;
weight = Math::sign(1.0, weight);
}
else if ( weight == 0.0 ) continue;
} else if ( weight == 0.0 ) continue;
accept();
// Divide by the bias introduced by the preweights in the reader.
weight /= currentReader()->preweight;
// fact for weight normalization
double fact = theNormWeight ? double(selector().sum()/picobarn) : 1.;
try {
theLastXComb = currentReader()->getXComb();
//whether to use the LHE event number or not for the event identification
if(UseLHEEvent==0 || currentReader()->LHEEventNum() == -1) {
currentEvent(new_ptr(Event(lastParticles(), this, generator()->runName(),
generator()->currentEventNumber(), weight*fact )));
}
else if(UseLHEEvent==1 && currentReader()->LHEEventNum() != -1) {
currentEvent(new_ptr(Event(lastParticles(), this, generator()->runName(),
currentReader()->LHEEventNum(), weight*fact )));
}
currentEvent()->optionalWeights() = currentReader()->optionalEventWeights();
// normalize the optional weights
for(map<string,double>::iterator it = currentEvent()->optionalWeights().begin();
it!=currentEvent()->optionalWeights().end();++it) {
if(it->first!="ecom"&& it->second!=-999 && it->second!=-111 && it->second!=-222 && it->second!=-333) { it->second *= fact; }
}
//print optional weights here
// cout << "event weight = " << weight << " fact = " << fact << endl;
/*for (map<string,double>::const_iterator it= currentReader()->optionalEventWeights().begin(); it!=currentReader()->optionalEventWeights().end(); ++it){
std::cout << it->first << " => " << it->second << '\n';
}
cout << endl;*/
//print npLO and npNLO
// cout << currentReader()->optionalEventnpLO() << "\t" << currentReader()->optionalEventnpNLO() << endl;
performCollision();
if ( !currentCollision() ) throw Veto();
return currentEvent();
}
catch (Veto) {
reject(weight);
}
catch (Stop) {
}
catch (Exception &) {
reject(weight);
throw;
}
}
}
void FxFxEventHandler::skipEvents() {
if ( weightOption() == 2 || weightOption() == -2 ) return; //does it make sense to skip events if we are using varying weights?
// Don't do this for readers which seem to generate events on the fly.
if ( currentReader()->active() || currentReader()->NEvents() <= 0 ) return;
// Estimate the fration of the total events available from
// currentReader() which will be requested.
double frac = currentReader()->stats.maxXSec()/stats.maxXSec();
if ( stats.accepted() > 0 )
frac *= double(stats.attempts())/double(stats.accepted());
else
frac *= double(stats.attempts() + 1);
double xscan = generator()->N()*frac/currentReader()->NEvents();
// Estimate the number of times we need to go through the events for
// the currentReader(), and how many events on average we need to
// skip for each attempted event to go through the file an integer
// number of times.
double nscan = ceil(xscan);
double meanskip = nscan/xscan - 1.0;
// Skip an average numer of steps with a Poissonian distribution.
currentReader()->
skip(UseRandom::rndPoisson(meanskip)%currentReader()->NEvents());
}
void FxFxEventHandler::select(double weight) {
stats.select(weight);
currentReader()->select(weight);
vector<double> w;
for (map<string,double>::const_iterator it= currentReader()->optionalEventWeights().begin(); it!=currentReader()->optionalEventWeights().end(); ++it){
w.push_back(it->second);
}
int ii = 0;
for (map<string,XSecStat>::iterator it= opthistStats.begin(); it!=opthistStats.end(); ++it){
(it->second).select(w[ii]);
ii++;
}
ii = 0;
for (map<string,XSecStat>::iterator it= optstats.begin(); it!=optstats.end(); ++it){
(it->second).select(w[ii]);
ii++;
}
}
tCollPtr FxFxEventHandler::performCollision() {
lastExtractor()->select(lastXCombPtr());
if ( CKKWHandler() ) CKKWHandler()->setXComb(lastXCombPtr());
currentCollision(new_ptr(Collision(lastParticles(), currentEvent(), this)));
if ( currentEvent() ) currentEvent()->addCollision(currentCollision());
currentStep(new_ptr(Step(currentCollision(), this)));
currentCollision()->addStep(currentStep());
currentStep()->addSubProcess(currentReader()->getSubProcess());
lastExtractor()->constructRemnants(lastXCombPtr()->partonBinInstances(),
subProcess(), currentStep());
if ( !currentReader()->cuts().passCuts(*currentCollision()) ) throw Veto();
initGroups();
if ( ThePEG_DEBUG_ITEM(1) ) {
if ( currentEvent() )
generator()->logfile() << *currentEvent();
else
generator()->logfile() << *currentCollision();
}
return continueCollision();
}
EventPtr FxFxEventHandler::continueEvent() {
try {
continueCollision();
}
catch (Veto) {
const double fact =
theNormWeight ?
double(selector().sum()/picobarn) : 1.;
reject(currentEvent()->weight()/fact);
}
catch (Stop) {
}
catch (Exception &) {
const double fact =
theNormWeight ?
double(selector().sum()/picobarn) : 1.;
reject(currentEvent()->weight()/fact);
throw;
}
return currentEvent();
}
void FxFxEventHandler::dofinish() {
EventHandler::dofinish();
if ( selector().compensating() ) generator()->log()
<< "Warning: The run was ended while the FxFxEventHandler '"
<< name() << "' was still trying to compensate for weights larger than 1. "
<< "The cross section estimates may therefore be statistically "
<< "inaccurate." << endl;
}
void FxFxEventHandler::statistics(ostream & os) const {
if ( statLevel() == 0 ) return;
string line = "======================================="
"=======================================\n";
if ( stats.accepted() <= 0 ) {
os << line << "No events generated by event handler '" << name() << "'."
<< endl;
return;
}
os << line << "Statistics for Les Houches event handler \'" << name() << "\':\n"
<< " "
<< "generated number of Cross-section\n"
<< " "
<< " events attempts (nb)\n";
os << line << "Total:" << setw(42) << stats.accepted() << setw(13)
<< stats.attempts() << setw(17)
<< ouniterr(stats.xSec(), stats.xSecErr(), nanobarn) << endl
<< line;
if ( statLevel() == 1 ) return;
if ( statLevel() == 2 ) {
os << "Per Les Houches Reader breakdown:\n";
for ( int i = 0, N = readers().size(); i < N; ++i ) {
FxFxReader & reader = *readers()[i];
string n = reader.name();
n.resize(37, ' ');
os << n << setw(11) << reader.stats.accepted() << setw(13)
<< reader.stats.attempts() << setw(17)
<< ouniterr(reader.stats.xSec(), reader.stats.xSecErr(), nanobarn)
<< endl;
}
os << line;
} else {
os << "Per Les Houches Reader (and process #) breakdown:\n";
for ( int i = 0, N = readers().size(); i < N; ++i ) {
FxFxReader & reader = *readers()[i];
string n = reader.name() + " (all)";
n.resize(37, ' ');
os << n << setw(11) << reader.stats.accepted() << setw(13)
<< reader.stats.attempts() << setw(17)
<< ouniterr(reader.stats.xSec(), reader.stats.xSecErr(), nanobarn)
<< endl;
CrossSection xsectot = reader.stats.xSec();
if ( xsectot != ZERO ) xsectot /= reader.stats.sumWeights();
typedef FxFxReader::StatMap::const_iterator const_iterator;
for ( const_iterator i = reader.statmap.begin();
i != reader.statmap.end(); ++i ) {
ostringstream ss;
ss << reader.name() << " (" << i->first << ")";
string n = ss.str();
n.resize(37, ' ');
os << n << setw(11) << i->second.accepted() << setw(13)
<< i->second.attempts() << setw(17)
<< ouniterr(i->second.sumWeights()*xsectot,
sqrt(i->second.sumWeights2())*xsectot, nanobarn) << endl;
}
os << line;
}
}
string warn = "Warning: Result may be statistically incorrect since\n"
" the following FxFxReaders were oversampled:\n";
for ( int i = 0, N = readers().size(); i < N; ++i ) {
FxFxReader & reader = *readers()[i];
if ( reader.NEvents() > 0 && reader.stats.attempts() > reader.NEvents() ) {
os << warn;
warn = "";
os << "'" << reader.name() << "' (by a factor "
<< double(reader.stats.attempts())/double(reader.NEvents())
<< ")" << endl;
}
}
}
void FxFxEventHandler::increaseMaxXSec(CrossSection maxxsec) {
stats.maxXSec(selector().sum());
histStats.maxXSec(selector().sum());
currentReader()->increaseMaxXSec(maxxsec);
}
void FxFxEventHandler::accept() {
ntries++;
stats.accept();
histStats.accept();
currentReader()->accept();
for (map<string,XSecStat>::iterator it= opthistStats.begin(); it!=opthistStats.end(); ++it){
(it->second).accept();
}
for (map<string,XSecStat>::iterator it= optstats.begin(); it!=optstats.end(); ++it){
(it->second).accept();
}
}
void FxFxEventHandler::reject(double w) {
ntries++;
stats.reject(w);
histStats.reject(w);
currentReader()->reject(w);
vector<double> wv;
for (map<string,double>::const_iterator it= currentReader()->optionalEventWeights().begin(); it!=currentReader()->optionalEventWeights().end(); ++it){
wv.push_back(it->second);
}
int ii = 0;
for (map<string,XSecStat>::iterator it= opthistStats.begin(); it!=opthistStats.end(); ++it){
(it->second).reject(wv[ii]);
ii++;
}
ii = 0;
for (map<string,XSecStat>::iterator it= optstats.begin(); it!=optstats.end(); ++it){
(it->second).reject(wv[ii]);
ii++;
}
}
map<string,CrossSection> FxFxEventHandler::optintegratedXSecMap() const {
map<string,CrossSection> result;
for (map<string,XSecStat>::const_iterator it= optstats.begin(); it!=optstats.end(); ++it){
result[it->first] = (it->second.sumWeights()/it->second.attempts()) * picobarn;
}
return result;
}
CrossSection FxFxEventHandler::histogramScale() const {
return histStats.xSec()/histStats.sumWeights();
}
CrossSection FxFxEventHandler::integratedXSec() const {
return histStats.xSec();
}
CrossSection FxFxEventHandler::integratedXSecErr() const {
return histStats.xSecErr();
}
int FxFxEventHandler::ntriesinternal() const {
return stats.attempts();
}
void FxFxEventHandler::persistentOutput(PersistentOStream & os) const {
os << stats << histStats << theReaders << theSelector
<< oenum(theWeightOption) << theUnitTolerance << theCurrentReader << warnPNum
<< theNormWeight << UseLHEEvent;
}
void FxFxEventHandler::persistentInput(PersistentIStream & is, int) {
is >> stats >> histStats >> theReaders >> theSelector
>> ienum(theWeightOption) >> theUnitTolerance >> theCurrentReader >> warnPNum
>> theNormWeight >> UseLHEEvent;;
}
ClassDescription<FxFxEventHandler>
FxFxEventHandler::initFxFxEventHandler;
// Definition of the static class description member.
void FxFxEventHandler::setUnitTolerance(double x) {
theUnitTolerance = x;
selector().tolerance(unitTolerance());
}
void FxFxEventHandler::Init() {
static ClassDocumentation<FxFxEventHandler> documentation
("This is the main class administrating the selection of hard "
"subprocesses from a set of ThePEG::FxFxReader objects.");
static RefVector<FxFxEventHandler,FxFxReader>
interfaceFxFxReaders
("FxFxReaders",
"Objects capable of reading events from an event file or an "
"external matrix element generator.",
&FxFxEventHandler::theReaders, -1, false, false, true, false, false);
static Switch<FxFxEventHandler,WeightOpt> interfaceWeightOption
("WeightOption",
"The different ways to weight events in the Les Houches event handler. "
"Whether weighted or not and whether or not negative weights are allowed.",
&FxFxEventHandler::theWeightOption, unitweight, true, false);
static SwitchOption interfaceWeightOptionUnitWeight
(interfaceWeightOption,
"UnitWeight",
"All events have unit weight.",
unitweight);
static SwitchOption interfaceWeightOptionNegUnitWeight
(interfaceWeightOption,
"NegUnitWeight",
"All events have weight +1 or maybe -1.",
unitnegweight);
static SwitchOption interfaceWeightOptionVarWeight
(interfaceWeightOption,
"VarWeight",
"Events may have varying but positive weights.",
varweight);
static SwitchOption interfaceWeightOptionVarNegWeight
(interfaceWeightOption,
"VarNegWeight",
"Events may have varying weights, both positive and negative.",
varnegweight);
static Switch<FxFxEventHandler,bool> interfaceWarnPNum
("WarnPNum",
"Warn if the same process number is used in more than one "
"FxFxReader.",
&FxFxEventHandler::warnPNum, true, true, false);
static SwitchOption interfaceWarnPNumWarning
(interfaceWarnPNum,
"Warning",
"Give a warning message.",
true);
static SwitchOption interfaceWarnPNumNoWarning
(interfaceWarnPNum,
"NoWarning",
"Don't give a warning message.",
false);
static Parameter<FxFxEventHandler,double> interfaceUnitTolerance
("UnitTolerance",
"If the <interface>WeightOption</interface> is set to unit weight, do not start compensating unless the a weight is found to be this much larger than unity.",
&FxFxEventHandler::theUnitTolerance, 1.0e-6, 0.0, 0,
true, false, Interface::lowerlim,
&FxFxEventHandler::setUnitTolerance,
(double(FxFxEventHandler::*)()const)(0),
(double(FxFxEventHandler::*)()const)(0),
(double(FxFxEventHandler::*)()const)(0),
(double(FxFxEventHandler::*)()const)(0));
static Switch<FxFxEventHandler,unsigned int> interfaceWeightNormalization
("WeightNormalization",
"How to normalize the output weights",
&FxFxEventHandler::theNormWeight, 0, false, false);
static SwitchOption interfaceWeightNormalizationUnit
(interfaceWeightNormalization,
"Normalized",
"Standard normalization, i.e. +/- for unweighted events",
0);
static SwitchOption interfaceWeightNormalizationCrossSection
(interfaceWeightNormalization,
"CrossSection",
"Normalize the weights to the max cross section in pb",
1);
static Switch<FxFxEventHandler,unsigned int> interfaceEventNumbering
("EventNumbering",
"How to number the events",
&FxFxEventHandler::UseLHEEvent, 0, false, false);
static SwitchOption interfaceEventNumberingIncremental
(interfaceEventNumbering,
"Incremental",
"Standard incremental numbering (i.e. as they are generated)",
0);
static SwitchOption interfaceEventNumberingLHE
(interfaceEventNumbering,
"LHE",
"Corresponding to the LHE event number",
1);
interfaceFxFxReaders.rank(10);
interfaceWeightOption.rank(9);
}
diff --git a/MatrixElement/FxFx/FxFxEventHandler.h b/MatrixElement/FxFx/FxFxEventHandler.h
--- a/MatrixElement/FxFx/FxFxEventHandler.h
+++ b/MatrixElement/FxFx/FxFxEventHandler.h
@@ -1,452 +1,444 @@
// -*- C++ -*-
//
// FxFxEventHandler.h is a part of ThePEG - Toolkit for HEP Event Generation
// Copyright (C) 1999-2019 Leif Lonnblad
//
// ThePEG is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef THEPEG_FxFxEventHandler_H
#define THEPEG_FxFxEventHandler_H
//
// This is the declaration of the FxFxEventHandler class.
//
#include "ThePEG/Handlers/EventHandler.h"
#include "FxFxEventHandler.fh"
#include "FxFxReader.fh"
#include "ThePEG/Utilities/CompSelector.h"
#include "ThePEG/Utilities/XSecStat.h"
namespace ThePEG {
/**
* The FxFxEventHandler inherits from the general EventHandler
* class and administers the reading of events generated by external
* matrix element generator programs according to the Les Houches
* accord.
*
* The class has a list of <code>FxFxReader</code>s which
* typically are connected to files with event data produced by
* external matrix element generator programs. When an event is
* requested by FxFxEventHandler, one of the readers are chosen,
* an event is read in and then passed to the different
* <code>StepHandler</code> defined in the underlying
* EventHandler class.
*
* @see \ref FxFxEventHandlerInterfaces "The interfaces"
* defined for FxFxEventHandler.
*/
class FxFxEventHandler: public EventHandler {
public:
/**
* A vector of FxFxReader objects.
*/
typedef vector<FxFxReaderPtr> ReaderVector;
/**
* A selector of readers.
*/
typedef CompSelector<int,CrossSection> ReaderSelector;
/**
* Enumerate the weighting options.
*/
enum WeightOpt {
unitweight = 1, /**< All events have unit weight. */
unitnegweight = -1, /**< All events have wight +/- 1. */
varweight = 2, /**< Varying positive weights. */
varnegweight = -2 /**< Varying positive or negative weights. */
};
friend class FxFxHandler;
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FxFxEventHandler()
: theWeightOption(unitweight), theUnitTolerance(1.0e-6), warnPNum(true), theNormWeight(0), UseLHEEvent(0)
{
selector().tolerance(unitTolerance());
}
- /**
- * The destructor.
- */
- virtual ~FxFxEventHandler();
- //@}
-
public:
/** @name Initialization and finalization functions. */
//@{
/**
* Initialize this event handler and all related objects needed to
* generate events.
*/
virtual void initialize();
/**
* Write out accumulated statistics about intergrated cross sections
* and stuff.
*/
virtual void statistics(ostream &) const;
/**
* Histogram scale. A histogram bin which has been filled with the
* weights associated with the Event objects should be scaled by
* this factor to give the correct cross section.
*/
virtual CrossSection histogramScale() const;
/**
* The estimated total integrated cross section of the processes
* generated in this run.
* @return 0 if no integrated cross section could be estimated.
*/
virtual CrossSection integratedXSec() const;
virtual int ntriesinternal() const;
/**
* The estimated error in the total integrated cross section of the
* processes generated in this run.
* @return 0 if no integrated cross section error could be estimated.
*/
virtual CrossSection integratedXSecErr() const;
virtual map<string,CrossSection> optintegratedXSecMap() const;
//@}
/** @name Functions used for the actual generation */
//@{
/**
* Generate an event.
*/
virtual EventPtr generateEvent();
/**
* Create the Event and Collision objects. Used by the
* generateEvent() function.
*/
virtual tCollPtr performCollision();
/**
* Continue generating an event if the generation has been stopped
* before finishing.
*/
virtual EventPtr continueEvent();
//@}
/** @name Functions to manipulate statistics. */
//@{
/**
* An event has been selected. Signal that an event has been
* selected with the given \a weight. If unit weights are requested,
* the event will be accepted with that weight. This also takes care
* of the statistics collection of the selected reader object.
*/
void select(double weight);
/**
* Accept the current event, taking care of the statistics
* collection of the corresponding reader objects.
*/
void accept();
/**
* Reject the current event, taking care of the statistics
* collection of the corresponding reader objects.
*/
void reject(double weight);
/**
* Increase the overestimated cross section for the selected reader.
*/
void increaseMaxXSec(CrossSection maxxsec);
/**
* Skip some events. To ensure a reader file is scanned an even
* number of times, skip a number of events for the selected reader.
*/
void skipEvents();
//@}
/** @name Simple access functions. */
//@{
/**
* The way weights are to be treated.
*/
WeightOpt weightOption() const { return theWeightOption; }
/**
* If the weight option is set to unit weight, do not start
* compensating unless the weight is this much larger than unity.
*/
double unitTolerance() const { return theUnitTolerance; }
/**
* Access the list of readers.
*/
const ReaderVector & readers() const { return theReaders; }
/**
* The selector to choose readers according to their overestimated
* cross section.
*/
const ReaderSelector & selector() const { return theSelector; }
/**
* The currently selected reader object.
*/
tFxFxReaderPtr currentReader() const { return theCurrentReader; }
/**
* Set the currently selected reader object.
*/
void currentReader(tFxFxReaderPtr x) { theCurrentReader = x; }
//@}
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();
/**
* The currently selected reader object.
*/
tFxFxReaderPtr theCurrentReader;
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();
//@}
protected:
/**
* Access the list of readers.
*/
ReaderVector & readers() { return theReaders; }
/**
* The selector to choose readers according to their overestimated
* cross section.
*/
ReaderSelector & selector() { return theSelector; }
/**
* Helper function for the interface;
*/
void setUnitTolerance(double);
/**
* Collect statistics for this event handler.
*/
XSecStat stats;
map<string,XSecStat> optstats;
map<string,CrossSection> optxs;
int ntries;
map<string,XSecStat> OptStatsFunc() { return optstats; }
map<string,CrossSection> OptXsFunc() { return optxs; }
/**
* Collect statistics for this event handler. To be used for
* histogram scaling.
*/
XSecStat histStats;
map<string,XSecStat> opthistStats;
/*
* The weight identifiers for the events
*/
vector<string> weightnames;
private:
/**
* The list of readers.
*/
ReaderVector theReaders;
/**
* The selector to choose readers according to their overestimated
* cross section.
*/
ReaderSelector theSelector;
/**
* The way weights are to be treated.
*/
WeightOpt theWeightOption;
/**
* If the weight option is set to unit weight, do not start
* compensating unless the weight is this much larger than unity.
*/
double theUnitTolerance;
/**
* Warn if the same process number is used in more than one
* FxFxReader.
*/
bool warnPNum;
/**
* How to normalize the weights
*/
unsigned int theNormWeight;
/**
* How to number the events
*/
unsigned int UseLHEEvent;
public:
/** @cond EXCEPTIONCLASSES */
/**
* Exception class used if no readers were assigned.
*/
class FxFxInitError: public InitException {};
/**
* Exception class used if the same process number is used by more
* than ne reader.
*/
class FxFxPNumException: public InitException {};
/** @endcond */
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FxFxEventHandler> initFxFxEventHandler;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FxFxEventHandler & operator=(const FxFxEventHandler &) = delete;
};
}
// CLASSDOC OFF
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FxFxEventHandler. */
template <>
struct BaseClassTrait<FxFxEventHandler,1> {
/** Typedef of the first base class of FxFxEventHandler. */
typedef EventHandler NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FxFxEventHandler class and the shared object where it is defined. */
template <>
struct ClassTraits<FxFxEventHandler>
: public ClassTraitsBase<FxFxEventHandler> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FxFxEventHandler"; }
/** Return the name of the shared library be loaded to get access to
* the FxFxEventHandler class and every other class it uses
* (except the base class). */
static string library() { return "HwFxFx.so"; }
};
/** @endcond */
}
#endif /* THEPEG_FxFxEventHandler_H */
diff --git a/MatrixElement/FxFx/FxFxFileReader.cc b/MatrixElement/FxFx/FxFxFileReader.cc
--- a/MatrixElement/FxFx/FxFxFileReader.cc
+++ b/MatrixElement/FxFx/FxFxFileReader.cc
@@ -1,946 +1,944 @@
// -*- C++ -*-
//
// FxFxFileReader.cc is a part of ThePEG - Toolkit for HEP Event Generation
// Copyright (C) 1999-2019 Leif Lonnblad
//
// ThePEG is licenced under version 3 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 FxFxFileReader class.
//
#include "FxFxFileReader.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Utilities/Throw.h"
#include "ThePEG/PDT/DecayMode.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include <sstream>
#include <iostream>
using namespace ThePEG;
FxFxFileReader::
FxFxFileReader(const FxFxFileReader & x)
: FxFxReader(x), neve(x.neve), ieve(0),
LHFVersion(x.LHFVersion), outsideBlock(x.outsideBlock),
headerBlock(x.headerBlock), initComments(x.initComments),
initAttributes(x.initAttributes), eventComments(x.eventComments),
eventAttributes(x.eventAttributes),
theFileName(x.theFileName), theQNumbers(x.theQNumbers),
theIncludeFxFxTags(x.theIncludeFxFxTags),
theIncludeCentral(x.theIncludeCentral),
theDecayer(x.theDecayer) {}
-FxFxFileReader::~FxFxFileReader() {}
-
IBPtr FxFxFileReader::clone() const {
return new_ptr(*this);
}
IBPtr FxFxFileReader::fullclone() const {
return new_ptr(*this);
}
bool FxFxFileReader::preInitialize() const {
return true;
}
void FxFxFileReader::doinit() {
FxFxReader::doinit();
// are we using QNUMBERS
if(!theQNumbers) return;
// parse the header block and create
// any new particles needed in QNUMBERS blocks
string block = headerBlock;
string line = "";
bool readingSLHA = false;
int (*pf)(int) = tolower;
unsigned int newNumber(0);
do {
line = StringUtils::car(block,"\r\n");
block = StringUtils::cdr(block,"\r\n");
if(line[0]=='#') continue;
// are we reading the SLHA block
if(readingSLHA) {
// reached the end of slha block ?
if(line.find("</slha") != string::npos) {
readingSLHA = false;
break;
}
// remove trailing comment from line
vector<string> split = StringUtils::split(line,"#");
// check for a qnumbers block
transform(split[0].begin(), split[0].end(), split[0].begin(), pf);
// if not contine
if(split[0].find("block qnumbers")==string::npos)
continue;
// get name from comment
string name;
if(split.size()>=2) {
name = StringUtils::stripws(split[1]);
}
else {
++newNumber;
ostringstream tname;
tname << "NP" << newNumber;
name = tname.str();
}
// extract the PDG code
split = StringUtils::split(split[0]," ");
istringstream is(split[2]);
long PDGCode(0);
is >> PDGCode;
// get the charge, spin, colour and whether an antiparticle
int charge(0),spin(0),colour(0),anti(0);
for(unsigned int ix=0;ix<4;++ix) {
line = StringUtils::car(block,"\r\n");
block = StringUtils::cdr(block,"\r\n");
int dummy[2];
istringstream is(line);
is >> dummy[0] >> dummy[1];
switch (dummy[0]) {
case 1:
charge = dummy[1];
break;
case 2:
spin = dummy[1];
break;
case 3:
colour = dummy[1];
break;
case 4:
anti = dummy[1];
break;
default:
assert(false);
}
}
// check if particles already exist
PDPair newParticle;
newParticle.first = getParticleData(PDGCode);
if(newParticle.first) Throw<SetupException>()
<< "Particle with PDG code " << PDGCode
<< " whose creation was requested in a QNUMBERS Block"
<< " already exists. Retaining the original particle"
<< Exception::warning;
if(anti) {
newParticle.second = getParticleData(-PDGCode);
if(newParticle.second) Throw<SetupException>()
<< "Anti-particle with PDG code " << -PDGCode
<< " whose creation was requested in a QNUMBERS Block"
<< " already exists. Retaining the original particle"
<< Exception::warning;
if(( newParticle.first && !newParticle.second ) ||
( newParticle.second && !newParticle.first ) )
Throw<SetupException>()
<< "Either particle or anti-particle with PDG code " << PDGCode
<< " whose creation was requested in a QNUMBERS Block"
<< " already exists, but not both the particle and antiparticle. "
<< " Something dodgy here stopping"
<< Exception::runerror;
}
// already exists continue
if(newParticle.first) continue;
// create the particles
// particle with no anti particle
if( anti == 0 ) {
// construct the name
if(name=="") {
ostringstream temp;
temp << PDGCode;
name = temp.str();
}
// create the ParticleData object
newParticle.first = ParticleData::Create(PDGCode,name);
}
// particle anti-particle pair
else {
// construct the names
string nameAnti;
if(name=="") {
ostringstream temp;
temp << PDGCode;
name = temp.str();
ostringstream temp2;
temp << -PDGCode;
nameAnti = temp2.str();
}
else {
nameAnti=name;
for(string::iterator it=nameAnti.begin();it!=nameAnti.end();++it) {
if(*it=='+') nameAnti.replace(it,it+1,"-");
else if(*it=='-') nameAnti.replace(it,it+1,"+");
}
if(nameAnti==name) nameAnti += "bar";
}
// create the ParticleData objects
newParticle = ParticleData::Create(PDGCode,name,nameAnti);
}
// set the particle properties
if(colour==1) colour = 0;
newParticle.first->iColour(PDT::Colour(colour));
newParticle.first->iSpin (PDT::Spin (spin ));
newParticle.first->iCharge(PDT::Charge(charge));
// register it
generator()->preinitRegister(newParticle.first,
"/Herwig/Particles/"+newParticle.first->PDGName());
// set the antiparticle properties
if(newParticle.second) {
if(colour==3||colour==6) colour *= -1;
charge = -charge;
newParticle.second->iColour(PDT::Colour(colour));
newParticle.second->iSpin (PDT::Spin (spin ));
newParticle.second->iCharge(PDT::Charge(charge));
// register it
generator()->preinitRegister(newParticle.second,
"/Herwig/Particles/"+newParticle.second->PDGName());
}
}
// start of SLHA block ?
else if(line.find("<slha") != string::npos) {
readingSLHA = true;
}
}
while(line!="");
// now set any masses/decay modes
block = headerBlock;
line="";
readingSLHA=false;
bool ok=true;
do {
line = StringUtils::car(block,"\r\n");
block = StringUtils::cdr(block,"\r\n");
// are we reading the SLHA block
if(readingSLHA) {
// reached the end?
if(line.find("</slha") == 0 ) {
readingSLHA = false;
break;
}
// make lower case
transform(line.begin(),line.end(),line.begin(), pf);
// found the mass block ?
if(line.find("block mass")!=string::npos) {
// read it
line = StringUtils::car(block,"\r\n");
// check not at end
while(line[0] != 'D' && line[0] != 'B' &&
line[0] != 'd' && line[0] != 'b' &&
line != "") {
// skip comment lines
if(line[0] == '#') {
block = StringUtils::cdr(block,"\r\n");
line = StringUtils::car(block,"\r\n");
continue;
}
// get the mass and PGD code
istringstream temp(line);
long id;
double mass;
temp >> id >> mass;
// skip resetting masses on SM particles
// as it can cause problems later on in event generation
if(abs(id)<=6 || (abs(id)>=11 && abs(id)<=16) ||
abs(id)==23 || abs(id)==24) {
// Throw<SetupException>() << "Standard model mass for PID "
// << id
// << " will not be changed."
// << Exception::warning;
block = StringUtils::cdr(block,"\r\n");
line = StringUtils::car(block,"\r\n");
continue;
}
// magnitude of mass for susy models
mass = abs(mass);
// set the mass
tPDPtr particle = getParticleData(id);
if(!particle) throw SetupException()
<< "FxFxFileReader::doinit() - Particle with PDG code not"
<< id << " not found." << Exception::runerror;
const InterfaceBase * ifb = BaseRepository::FindInterface(particle,
"NominalMass");
ostringstream os;
os << mass;
ifb->exec(*particle, "set", os.str());
// read the next line
block = StringUtils::cdr(block,"\r\n");
line = StringUtils::car(block,"\r\n");
};
}
// found a decay block
else if(line.find("decay") == 0) {
// get PGD code and width
istringstream iss(line);
string dummy;
long parent(0);
Energy width(ZERO);
iss >> dummy >> parent >> iunit(width, GeV);
// get the ParticleData object
PDPtr inpart = getParticleData(parent);
if(!inpart) {
throw SetupException()
<< "FxFxFileReader::doinit() - A ParticleData object with the PDG code "
<< parent << " does not exist. " << Exception::runerror;
return;
}
if ( abs(inpart->id()) == 6 ||
abs(inpart->id()) == 15 ||
abs(inpart->id()) == 23 ||
abs(inpart->id()) == 24 ||
abs(inpart->id()) == 25 ) {
Throw<SetupException>() << "\n"
"************************************************************************\n"
"* Your LHE file changes the width of " << inpart->PDGName() << ".\n"
"* This can cause serious problems in the event generation!\n"
"************************************************************************\n"
"\n" << Exception::warning;
}
else if (inpart->width() > ZERO && width <= ZERO) {
Throw<SetupException>() << "\n"
"************************************************************************\n"
"* Your LHE file zeroes the non-zero width of " << inpart->PDGName() << ".\n"
"* If " << inpart->PDGName() << " is a decaying SM particle,\n"
"* this can cause serious problems in the event generation!\n"
"************************************************************************\n"
"\n" << Exception::warning;
}
// set the width
inpart->width(width);
if( width > ZERO ) {
inpart->cTau(hbarc/width);
inpart->widthCut(5.*width);
inpart->stable(false);
}
// construct prefix for DecayModes
string prefix(inpart->name() + "->"), tag(prefix),line("");
unsigned int nmode(0);
// read any decay modes
line = StringUtils::car(block,"\r\n");
while(line[0] != 'D' && line[0] != 'B' &&
line[0] != 'd' && line[0] != 'b' &&
line[0] != '<' && line != "") {
// skip comments
if(line[0] == '#') {
block = StringUtils::cdr(block,"\r\n");
line = StringUtils::car(block,"\r\n");
continue;
}
// read decay mode and construct the tag
istringstream is(line);
double brat(0.);
unsigned int nda(0),npr(0);
is >> brat >> nda;
while( true ) {
long t;
is >> t;
if( is.fail() ) break;
if( t == abs(parent) )
throw SetupException()
<< "An error occurred while read a decay of the "
<< inpart->PDGName() << ". One of its products has the same PDG code "
<< "as the parent particle in FxFxFileReader::doinit()."
<< " Please check the Les Houches file.\n"
<< Exception::runerror;
tcPDPtr p = getParticleData(t);
if( !p )
throw SetupException()
<< "FxFxFileReader::doinit() -"
<< " An unknown PDG code has been encounterd "
<< "while reading a decay mode. ID: " << t
<< Exception::runerror;
++npr;
tag += p->name() + ",";
}
if( npr != nda )
throw SetupException()
<< "FxFxFileReader::doinit() - While reading a decay of the "
<< inpart->PDGName() << " from an SLHA file, an inconsistency "
<< "between the number of decay products and the value in "
<< "the 'NDA' column was found. Please check if the spectrum "
<< "file is correct.\n"
<< Exception::warning;
// create the DecayMode
if( npr > 1 ) {
if( nmode==0 ) {
generator()->preinitInterface(inpart, "VariableRatio" , "set","false");
if(inpart->massGenerator()) {
ok = false;
Throw<SetupException>()
<< inpart->PDGName() << " already has a WidthGenerator set"
<< " this is incompatible with using QNUMBERS "
<< "Use\n"
<< "set " << inpart->fullName() << ":Width_generator NULL\n"
<< "to fix this." << Exception::warning;
}
unsigned int ntemp=0;
for(DecaySet::const_iterator dit = inpart->decayModes().begin();
dit != inpart->decayModes().end(); ++dit ) {
if((**dit).on()) ++ntemp;
}
if(ntemp!=0) {
ok = false;
Throw<SetupException>()
<< inpart->PDGName() << " already has DecayModes"
<< " this is incompatible with using QNUMBERS "
<< "Use\n"
<< "do " << inpart->fullName() << ":SelectDecayModes none\n"
<< " to fix this." << Exception::warning;
}
}
inpart->stable(false);
tag.replace(tag.size() - 1, 1, ";");
DMPtr dm = generator()->findDecayMode(tag);
if(!theDecayer) Throw<SetupException>()
<< "FxFxFileReader::doinit() Decayer must be set using the "
<< "FxFxFileReader:Decayer"
<< " must be set to allow the creation of new"
<< " decay modes."
<< Exception::runerror;
if(!dm) {
dm = generator()->preinitCreateDecayMode(tag);
if(!dm)
Throw<SetupException>()
<< "FxFxFileReader::doinit() - Needed to create "
<< "new decaymode but one could not be created for the tag "
<< tag << Exception::warning;
}
generator()->preinitInterface(dm, "Decayer", "set",
theDecayer->fullName());
ostringstream br;
br << setprecision(13) << brat;
generator()->preinitInterface(dm, "BranchingRatio", "set", br.str());
generator()->preinitInterface(dm, "Active", "set", "Yes");
if(dm->CC()) {
generator()->preinitInterface(dm->CC(), "BranchingRatio", "set", br.str());
generator()->preinitInterface(dm->CC(), "Active", "set", "Yes");
}
++nmode;
}
tag=prefix;
// read the next line
block = StringUtils::cdr(block,"\r\n");
line = StringUtils::car(block,"\r\n");
};
if(nmode>0) {
inpart->update();
if(inpart->CC())
inpart->CC()->update();
}
}
}
// start of SLHA block ?
else if(line.find("<slha") != string::npos) {
readingSLHA = true;
}
}
while(line!="");
if(!ok)
throw SetupException() << "Problem reading QNUMBERS blocks in FxFxFileReader::doinit()"
<< Exception::runerror;
}
void FxFxFileReader::initialize(FxFxEventHandler & eh) {
FxFxReader::initialize(eh);
if ( LHFVersion.empty() )
Throw<FxFxFileError>()
<< "The file associated with '" << name() << "' does not contain a "
<< "proper formatted Les Houches event file. The events may not be "
<< "properly sampled." << Exception::warning;
}
//vector<string> FxFxFileReader::optWeightNamesFunc() { return optionalWeightsNames; }
vector<string> FxFxFileReader::optWeightsNamesFunc() { return optionalWeightsNames; }
void FxFxFileReader::open() {
if ( filename().empty() )
throw FxFxFileError()
<< "No Les Houches file name. "
<< "Use 'set " << name() << ":FileName'."
<< Exception::runerror;
cfile.open(filename());
if ( !cfile )
throw FxFxFileError()
<< "The FxFxFileReader '" << name() << "' could not open the "
<< "event file called '" << theFileName << "'."
<< Exception::runerror;
cfile.readline();
if ( !cfile.find("<LesHouchesEvents") ) return;
map<string,string> attributes =
StringUtils::xmlAttributes("LesHouchesEvents", cfile.getline());
LHFVersion = attributes["version"];
//cout << LHFVersion << endl;
if ( LHFVersion.empty() ) return;
bool readingHeader = false;
bool readingInit = false;
headerBlock = "";
// char (cwgtinfo_weights_info[250][15]);
string hs;
// int cwgtinfo_nn(0);
// Loop over all lines until we hit the </init> tag.
bool readingInitWeights = false, readingInitWeights_sc = false;
string weightinfo;
while ( cfile.readline() ) {
// found the init block for multiple weights
if(cfile.find("<initrwgt")) { /*cout << "reading weights" << endl;*/ readingInitWeights = true; }
// found end of init block for multiple weights: end the while loop
if(cfile.find("</initrwgt")) { readingInitWeights = false; readingInitWeights_sc = false; continue;}
// found the end of init block
if(cfile.find("</init")) { readingInit = false; break; }
/* read the weight information block
* optionalWeightNames will contain information about the weights
* this will be appended to the weight information
*/
if(readingInitWeights) {
string scalename = "";
if(cfile.find("<weightgroup")) {
/* we found a weight group
* start reading the information
* within it
*/
readingInitWeights_sc = true;
weightinfo = cfile.getline();
/* to make it shorter, erase some stuff
*/
string str_weightgroup = "<weightgroup";
string str_arrow = ">";
string str_newline = "\n";
erase_substr(weightinfo, str_weightgroup);
erase_substr(weightinfo, str_arrow);
erase_substr(weightinfo, str_newline);
}
/* if we are reading a new weightgroup, go on
* until we find the end of it
*/
if(readingInitWeights_sc && !cfile.find("</weightgroup") && !cfile.find("<weightgroup")) {
hs = cfile.getline();
//cout << "hs=" << hs << endl;
//cout << "weightinfo= " << weightinfo << endl;
//fix for potential new lines:
if(!cfile.find("<weight") and !cfile.find("</weightgroup")) {
weightinfo = weightinfo + hs;
//cout << "weightinfo fixed= " << weightinfo << endl;
continue;
}
istringstream isc(hs);
int ws = 0;
/* get the name that will be used to identify the scale
*/
do {
string sub; isc >> sub;
if(ws==1) { string str_arrow = ">"; erase_substr(sub, str_arrow); scalename = sub; }
++ws;
} while (isc);
/* now get the relevant information
* e.g. scales or PDF sets used
*/
string startDEL = ">"; //starting delimiter
string stopDEL = "</weight>"; //end delimiter
unsigned firstLim = hs.find(startDEL); //find start of delimiter
// unsigned lastLim = hs.find(stopDEL); //find end of delimitr
string scinfo = hs.substr(firstLim); //define the information for the scale
erase_substr(scinfo,stopDEL);
erase_substr(scinfo,startDEL);
scinfo = StringUtils::stripws(scinfo);
//cout << "scinfo = " << scinfo << endl;
/* fill in the map
* indicating the information to be appended to each scale
* i.e. scinfo for each scalname
*/
scalemap[scalename] = scinfo.c_str();
string str_id = "id=";
string str_prime = "'";
erase_substr(scalename, str_id);
erase_substr(scalename, str_prime);
optionalWeightsNames.push_back(scalename);
}
}
if ( cfile.find("<header") ) {
// following lines to headerBlock until we hit the end of it.
readingHeader = true;
headerBlock = cfile.getline() + "\n";
}
if ( (cfile.find("<init ") && !cfile.find("<initrwgt")) || cfile.find("<init>") ) {
//cout << "found init block" << endl;
// We have hit the init block, so we should expect to find the
// standard information in the following. But first check for
// attributes.
initAttributes = StringUtils::xmlAttributes("init", cfile.getline());
readingInit = true;
cfile.readline();
if ( !( cfile >> heprup.IDBMUP.first >> heprup.IDBMUP.second
>> heprup.EBMUP.first >> heprup.EBMUP.second
>> heprup.PDFGUP.first >> heprup.PDFGUP.second
>> heprup.PDFSUP.first >> heprup.PDFSUP.second
>> heprup.IDWTUP >> heprup.NPRUP ) ) {
heprup.NPRUP = -42;
LHFVersion = "";
return;
}
heprup.resize();
for ( int i = 0; i < heprup.NPRUP; ++i ) {
cfile.readline();
if ( !( cfile >> heprup.XSECUP[i] >> heprup.XERRUP[i]
>> heprup.XMAXUP[i] >> heprup.LPRUP[i] ) ) {
heprup.NPRUP = -42;
LHFVersion = "";
return;
}
}
}
if ( cfile.find("</header") ) {
readingHeader = false;
headerBlock += cfile.getline() + "\n";
}
if ( readingHeader ) {
/* We are in the process of reading the header block. Dump the
line to headerBlock.*/
headerBlock += cfile.getline() + "\n";
}
if ( readingInit ) {
// Here we found a comment line. Dump it to initComments.
initComments += cfile.getline() + "\n";
}
}
string central = "central";
if (theIncludeCentral) optionalWeightsNames.push_back(central);
// cout << "reading init finished" << endl;
if ( !cfile ) {
heprup.NPRUP = -42;
LHFVersion = "";
return;
}
}
bool FxFxFileReader::doReadEvent() {
if ( !cfile ) return false;
if ( LHFVersion.empty() ) return false;
if ( heprup.NPRUP < 0 ) return false;
eventComments = "";
outsideBlock = "";
hepeup.NUP = 0;
hepeup.XPDWUP.first = hepeup.XPDWUP.second = 0.0;
optionalWeights.clear();
optionalWeightsTemp.clear();
// Keep reading lines until we hit the next event or the end of
// the event block. Save any inbetween lines. Exit if we didn't
// find an event.
while ( cfile.readline() && !cfile.find("<event") )
outsideBlock += cfile.getline() + "\n";
// We found an event. First scan for attributes.
eventAttributes = StringUtils::xmlAttributes("event", cfile.getline());
/* information necessary for FxFx merging:
* the npLO and npNLO tags
*/
istringstream ievat(cfile.getline());
int we(0), npLO(-10), npNLO(-10);
do {
string sub; ievat >> sub;
if(we==2) { npLO = atoi(sub.c_str()); }
if(we==5) { npNLO = atoi(sub.c_str()); }
++we;
} while (ievat);
optionalnpLO = npLO;
optionalnpNLO = npNLO;
std::stringstream npstringstream;
npstringstream << "np " << npLO << " " << npNLO;
std::string npstrings = npstringstream.str();
/* the FxFx merging information
* becomes part of the optionalWeights, labelled -999
* for future reference
*/
if(theIncludeFxFxTags) optionalWeights[npstrings.c_str()] = -999;
string ecomstring = "ecom";
optionalWeights[ecomstring.c_str()] = heprup.EBMUP.first+heprup.EBMUP.second;
if ( !cfile.readline() ) return false;
// The first line determines how many subsequent particle lines we
// have.
if ( !( cfile >> hepeup.NUP >> hepeup.IDPRUP >> hepeup.XWGTUP
>> hepeup.SCALUP >> hepeup.AQEDUP >> hepeup.AQCDUP ) )
return false;
hepeup.resize();
// Read all particle lines.
for ( int i = 0; i < hepeup.NUP; ++i ) {
if ( !cfile.readline() ) return false;
if ( !( cfile >> hepeup.IDUP[i] >> hepeup.ISTUP[i]
>> hepeup.MOTHUP[i].first >> hepeup.MOTHUP[i].second
>> hepeup.ICOLUP[i].first >> hepeup.ICOLUP[i].second
>> hepeup.PUP[i][0] >> hepeup.PUP[i][1] >> hepeup.PUP[i][2]
>> hepeup.PUP[i][3] >> hepeup.PUP[i][4]
>> hepeup.VTIMUP[i] >> hepeup.SPINUP[i] ) )
return false;
if(std::isnan(hepeup.PUP[i][0])||std::isnan(hepeup.PUP[i][1])||
std::isnan(hepeup.PUP[i][2])||std::isnan(hepeup.PUP[i][3])||
std::isnan(hepeup.PUP[i][4]))
throw Exception()
<< "nan's as momenta in Les Houches file "
<< Exception::eventerror;
if(hepeup.MOTHUP[i].first -1==i ||
hepeup.MOTHUP[i].second-1==i) {
throw Exception()
<< "Particle has itself as a mother in Les Houches "
<< "file, this is not allowed\n"
<< Exception::eventerror;
}
}
LHEeventnum = -1; // set the LHEeventnum to -1, this will be the default if the tag <event num> is not found
// Now read any additional comments and named weights.
// read until the end of rwgt is found
bool readingWeights = false, readingaMCFast = false, readingMG5ClusInfo = false;
while ( cfile.readline() && !cfile.find("</event>")) {
if(cfile.find("</applgrid")) { readingaMCFast=false; } //aMCFast weights end
if(cfile.find("</rwgt")) { readingWeights=false; } //optional weights end
if(cfile.find("</clustering")) { readingMG5ClusInfo=false; } // mg5 mclustering scale info end
/* reading of optional weights
*/
if(readingWeights) {
if(!cfile.find("<wgt")) { continue; }
istringstream iss(cfile.getline());
int wi = 0;
double weightValue(0);
string weightName = "";
// we need to put the actual weight value into a double
do {
string sub; iss >> sub;
if(wi==1) { string str_arrow = ">" ; erase_substr(sub, str_arrow); weightName = sub; }
if(wi==2) weightValue = atof(sub.c_str());
++wi;
} while (iss);
// store the optional weights found in the temporary map
//cout << "weightName, weightValue= " << weightName << ", " << weightValue << endl;
optionalWeightsTemp[weightName] = weightValue;
}
/* reading of aMCFast weights
*/
if(readingaMCFast) {
std::stringstream amcfstringstream;
amcfstringstream << "aMCFast " << cfile.getline();
std::string amcfstrings = amcfstringstream.str();
string str_newline = "\n";
erase_substr(amcfstrings,str_newline);
optionalWeights[amcfstrings.c_str()] = -111; //for the aMCFast we give them a weight -111 for future identification
}
/* read additional MG5 Clustering information
* used in LO merging
*/
if(readingMG5ClusInfo) {
string hs = cfile.getline();
string startDEL = "<clus scale="; //starting delimiter
string stopDEL = "</clus>"; //end delimiter
unsigned firstLim = hs.find(startDEL); //find start of delimiter
// unsigned lastLim = hs.find(stopDEL); //find end of delimitr
string mg5clusinfo = hs.substr(firstLim); //define the information for the scale
erase_substr(mg5clusinfo,stopDEL);
erase_substr(mg5clusinfo,startDEL);
string str_arrow = ">";
erase_substr(mg5clusinfo,str_arrow);
string str_quotation = "\"";
erase_substr(mg5clusinfo,str_quotation);
string str_newline= "\n";
erase_substr(mg5clusinfo,str_newline);
optionalWeights[mg5clusinfo.c_str()] = -222; //for the mg5 scale info weights we give them a weight -222 for future identification
}
//the event num tag
if(cfile.find("<event num")) {
string hs = cfile.getline();
string startDEL = "<event num"; //starting delimiter
string stopDEL = "</event num>"; //end delimiter
unsigned firstLim = hs.find(startDEL);
string LHEeventnum_str = hs.substr(firstLim);
erase_substr(LHEeventnum_str,stopDEL);
erase_substr(LHEeventnum_str,startDEL);
string str_arrow = ">";
erase_substr(LHEeventnum_str,str_arrow);
LHEeventnum = std::stol(LHEeventnum_str, nullptr, 10);
}
//store MG5 clustering information
if(cfile.find("<scales")) {
string hs = cfile.getline();
string startDEL = "<scales"; //starting delimiter
string stopDEL = "</scales>"; //end delimiter
unsigned firstLim = hs.find(startDEL); //find start of delimiter
// unsigned lastLim = hs.find(stopDEL); //find end of delimitr
string mg5scinfo = hs.substr(firstLim); //define the information for the scale
erase_substr(mg5scinfo,stopDEL);
erase_substr(mg5scinfo,startDEL);
string str_arrow = ">";
erase_substr(mg5scinfo,str_arrow);
string str_newline= "\n";
erase_substr(mg5scinfo,str_newline);
optionalWeights[mg5scinfo.c_str()] = -333; //for the mg5 scale info weights we give them a weight -333 for future identification
}
//determine start of aMCFast weights
if(cfile.find("<applgrid")) { readingaMCFast = true;}
//determine start of optional weights
if(cfile.find("<rwgt")) { readingWeights = true; }
//determine start of MG5 clustering scale information
if(cfile.find("<clustering")) { readingMG5ClusInfo = true;}
}
// loop over the optional weights and add the extra information as found in the init
for (map<string,double>::const_iterator it=optionalWeightsTemp.begin(); it!=optionalWeightsTemp.end(); ++it){
string itfirst = it->first;
erase_substr(itfirst, "'");
erase_substr(itfirst, "\"");
for (map<string,string>::const_iterator it2=scalemap.begin(); it2!=scalemap.end(); ++it2){
//find the scale id in the scale information and add this information
string it2first = it2->first;
erase_substr(it2first, "'");
erase_substr(it2first, "\"");
//cout << "itfirst, it2first = " << itfirst << "\t" << it2first << endl;
if(itfirst==it2first) {
string info = it2->second;
string str_newline = "\n";
erase_substr(info, str_newline);
//set the optional weights
optionalWeights[info] = it->second;
}
}
}
/* additionally, we set the "central" scale
* this is actually the default event weight
*/
string central = "central";
if (theIncludeCentral) optionalWeights[central] = hepeup.XWGTUP;
if ( !cfile ) return false;
return true;
}
void FxFxFileReader::close() {
cfile.close();
}
void FxFxFileReader::persistentOutput(PersistentOStream & os) const {
os << neve << LHFVersion << outsideBlock << headerBlock << initComments
<< initAttributes << eventComments << eventAttributes << theFileName
<< theQNumbers << theIncludeFxFxTags << theIncludeCentral << theDecayer;
}
void FxFxFileReader::persistentInput(PersistentIStream & is, int) {
is >> neve >> LHFVersion >> outsideBlock >> headerBlock >> initComments
>> initAttributes >> eventComments >> eventAttributes >> theFileName
>> theQNumbers >> theIncludeFxFxTags >> theIncludeCentral >> theDecayer;
ieve = 0;
}
ClassDescription<FxFxFileReader>
FxFxFileReader::initFxFxFileReader;
// Definition of the static class description member.
void FxFxFileReader::Init() {
static ClassDocumentation<FxFxFileReader> documentation
("ThePEG::FxFxFileReader is an base class to be used for objects "
"which reads event files from matrix element generators. This class is "
"able to read plain event files conforming to the Les Houches Event File "
"accord.");
static Parameter<FxFxFileReader,string> interfaceFileName
("FileName",
"The name of a file containing events conforming to the Les Houches "
"protocol to be read into ThePEG. A file name ending in "
"<code>.gz</code> will be read from a pipe which uses "
"<code>zcat</code>. If a file name ends in <code>|</code> the "
"preceeding string is interpreted as a command, the output of which "
"will be read through a pipe.",
&FxFxFileReader::theFileName, "", false, false);
interfaceFileName.fileType();
interfaceFileName.rank(11);
static Switch<FxFxFileReader,bool> interfaceQNumbers
("QNumbers",
"Whether or not to read search for and read a QNUMBERS"
" block in the header of the file.",
&FxFxFileReader::theQNumbers, false, false, false);
static SwitchOption interfaceQNumbersYes
(interfaceQNumbers,
"Yes",
"Use QNUMBERS",
true);
static SwitchOption interfaceQNumbersNo
(interfaceQNumbers,
"No",
"Don't use QNUMBERS",
false);
static Switch<FxFxFileReader,bool> interfaceIncludeFxFxTags
("IncludeFxFxTags",
"Include FxFx tags",
&FxFxFileReader::theIncludeFxFxTags, true, true, false);
static SwitchOption interfaceIncludeFxFxTagsYes
(interfaceIncludeFxFxTags,
"Yes",
"Use the FxFx tags",
true);
static SwitchOption interfaceIncludeFxFxTagsNo
(interfaceIncludeFxFxTags,
"No",
"Don't use the FxFx tags",
false);
static Switch<FxFxFileReader,bool> interfaceIncludeCentral
("IncludeCentral",
"Include definition of central weight",
&FxFxFileReader::theIncludeCentral, false, true, false);
static SwitchOption interfaceIncludeCentralYes
(interfaceIncludeCentral,
"Yes",
"include definition of central weight",
true);
static SwitchOption interfaceIncludeCentralNo
(interfaceIncludeCentral,
"No",
"Don't include definition of central weight",
false);
static Reference<FxFxFileReader,Decayer> interfaceDecayer
("Decayer",
"Decayer to use for any decays read from the QNUMBERS Blocks",
&FxFxFileReader::theDecayer, false, false, true, true, false);
}
void FxFxFileReader::erase_substr(std::string& subject, const std::string& search) {
size_t pos = 0;
while((pos = subject.find(search, pos)) != std::string::npos) {
subject.erase( pos, search.length() );
}
}
diff --git a/MatrixElement/FxFx/FxFxFileReader.h b/MatrixElement/FxFx/FxFxFileReader.h
--- a/MatrixElement/FxFx/FxFxFileReader.h
+++ b/MatrixElement/FxFx/FxFxFileReader.h
@@ -1,333 +1,325 @@
// -*- C++ -*-
//
// FxFxFileReader.h is a part of ThePEG - Toolkit for HEP Event Generation
// Copyright (C) 1999-2019 Leif Lonnblad
//
// ThePEG is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef THEPEG_FxFxFileReader_H
#define THEPEG_FxFxFileReader_H
// This is the declaration of the FxFxFileReader class.
#include "FxFxReader.h"
#include "FxFxFileReader.fh"
#include "ThePEG/PDT/Decayer.h"
#include "ThePEG/Utilities/CFileLineReader.h"
#include <stdio.h>
namespace ThePEG {
/**
* FxFxFileReader is an base class to be used for objects which
* reads event files from matrix element generators. It inherits from
* FxFxReader and extends it by defining a file handle to be
* read from, which is opened and closed by the open() and close()
* functions. Note that the file handle is a standard C filehandle and
* not a C++ stream. This is because there is no standard way in C++
* to connect a pipe to a stream for reading eg. gzipped files. This
* class is able to read plain event files conforming to the Les
* Houches Event File accord.
*
* @see \ref FxFxFileReaderInterfaces "The interfaces"
* defined for FxFxFileReader.
* @see Event
* @see FxFxReader
*/
class FxFxFileReader: public FxFxReader {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* Default constructor.
*/
FxFxFileReader() : neve(0), ieve(0), theQNumbers(false), theIncludeFxFxTags(true),
theIncludeCentral(false) {}
/**
* Copy-constructor. Note that a file which is opened in the object
* copied from will have to be reopened in this.
*/
FxFxFileReader(const FxFxFileReader &);
- /**
- * Destructor.
- */
- virtual ~FxFxFileReader();
- //@}
-
public:
/** @name Virtual functions specified by the FxFxReader base class. */
//@{
/**
* Initialize. This function is called by the FxFxEventHandler
* to which this object is assigned.
*/
virtual void initialize(FxFxEventHandler & eh);
/**
* Open a file with events. Derived classes should overwrite it and
* first calling it before reading in the run information into the
* corresponding protected variables.
*/
virtual void open();
/**
* Close the file from which events have been read.
*/
virtual void close();
/**
* Read the next event from the file or stream into the
* corresponding protected variables. Return false if there is no
* more events or if this was not a LHF event file.
*/
virtual bool doReadEvent();
//@}
/**
* Return the name of the file from where to read events.
*/
string filename() const { return theFileName; }
/* vector<string> optionalWeightsNames;
virtual vector<string> optWeightNamesFunc();*/
virtual vector<string> optWeightsNamesFunc();
/**
* Erases all occurences of a substring from a string
*/
void erase_substr(std::string& subject, const std::string& search);
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);
//@}
/**
* Standard Init function used to initialize the interfaces.
*/
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;
//@}
/** @name Standard (and non-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();
/**
* Return true if this object needs to be initialized before all
* other objects because it needs to extract PDFs from the event file.
*/
virtual bool preInitialize() const;
//@
protected:
/**
* The wrapper around the C FILE stream from which to read
*/
CFileLineReader cfile;
protected:
/**
* The number of events in this file.
*/
long neve;
/**
* The current event number.
*/
long ieve;
/**
* If the file is a standard Les Houches formatted file (LHF) this
* is its version number. If empty, this is not a Les Houches
* formatted file
*/
string LHFVersion;
/**
* If LHF. All lines (since the last open() or readEvent()) outside
* the header, init and event tags.
*/
string outsideBlock;
/**
* If LHF. All lines from the header block.
*/
string headerBlock;
/**
* If LHF. Additional comments found in the init block.
*/
string initComments;
/**
* If LHF. Map of attributes (name-value pairs) found in the init
* tag.
*/
map<string,string> initAttributes;
/**
* If LHF. Additional comments found with the last read event.
*/
string eventComments;
/**
* If LHF. Map of attributes (name-value pairs) found in the last
* event tag.
*/
map<string,string> eventAttributes;
private:
/**
* The name of the file from where to read events.
*/
string theFileName;
/**
* Whether or not to search for QNUMBERS stuff
*/
bool theQNumbers;
/**
* Include/Read FxFx tags
*/
bool theIncludeFxFxTags;
/**
* Include central weight (for backup use)
*/
bool theIncludeCentral;
/**
* Decayer for any decay modes read from the file
*/
DecayerPtr theDecayer;
/**
* Further information on the weights
*/
map<string,string> scalemap;
/**
* Temporary holder for optional weights
*/
map<string,double> optionalWeightsTemp;
private:
/**
* Describe an abstract base class with persistent data.
*/
static ClassDescription<FxFxFileReader> initFxFxFileReader;
/**
* Private and non-existent assignment operator.
*/
FxFxFileReader & operator=(const FxFxFileReader &) = delete;
public:
/** @cond EXCEPTIONCLASSES */
/** Exception class used by FxFxFileReader if reading the file
* fails. */
class FxFxFileError: public Exception {};
/** @endcond */
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/**
* This template specialization informs ThePEG about the
* base class of FxFxFileReader.
*/
template <>
struct BaseClassTrait<FxFxFileReader,1>: public ClassTraitsType {
/** Typedef of the base class of FxFxFileReader. */
typedef FxFxReader NthBase;
};
/**
* This template specialization informs ThePEG about the name of the
* FxFxFileReader class and the shared object where it is
* defined.
*/
template <>
struct ClassTraits<FxFxFileReader>
: public ClassTraitsBase<FxFxFileReader> {
/**
* Return the class name.
*/
static string className() { return "Herwig::FxFxFileReader"; }
/**
* Return the name of the shared library to be loaded to get access
* to the FxFxFileReader class and every other class it uses
* (except the base class).
*/
static string library() { return "HwFxFx.so"; }
};
/** @endcond */
}
#endif /* THEPEG_FxFxFileReader_H */
diff --git a/MatrixElement/FxFx/FxFxReader.cc b/MatrixElement/FxFx/FxFxReader.cc
--- a/MatrixElement/FxFx/FxFxReader.cc
+++ b/MatrixElement/FxFx/FxFxReader.cc
@@ -1,1605 +1,1605 @@
// -*- C++ -*-
//
// FxFxReader.cc is a part of ThePEG - Toolkit for HEP Event Generation
// Copyright (C) 1999-2019 Leif Lonnblad
//
// ThePEG is licenced under version 3 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 FxFxReader class.
//
#include "FxFxReader.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/Interface/Command.h"
//#include "config.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDF/PartonExtractor.h"
#include "ThePEG/PDF/NoPDF.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/EventRecord/TmpTransform.h"
#include "ThePEG/Utilities/UtilityBase.h"
#include "ThePEG/Handlers/XComb.h"
#include "ThePEG/Handlers/CascadeHandler.h"
#include "FxFxEventHandler.h"
#include "ThePEG/Utilities/Throw.h"
#include "ThePEG/Utilities/HoldFlag.h"
#include "ThePEG/Utilities/Debug.h"
#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
using namespace ThePEG;
FxFxReader::FxFxReader(bool active)
: theNEvents(0), position(0), reopened(0), theMaxScan(-1), scanning(false),
isActive(active), theCacheFileName(""), doCutEarly(true),
preweight(1.0), reweightPDF(false), doInitPDFs(false),
theMaxMultCKKW(0), theMinMultCKKW(0), lastweight(1.0), maxFactor(1.0), optionalnpLO(0), optionalnpNLO(0),
weightScale(1.0*picobarn), skipping(false), theMomentumTreatment(0),
useWeightWarnings(true),theReOpenAllowed(true), theIncludeSpin(true) {}
FxFxReader::FxFxReader(const FxFxReader & x)
: HandlerBase(x), LastXCombInfo<>(x), heprup(x.heprup), hepeup(x.hepeup),
inData(x.inData), inPDF(x.inPDF), outPDF(x.outPDF),
thePartonExtractor(x.thePartonExtractor), thePartonBins(x.thePartonBins),
theXCombs(x.theXCombs), theCuts(x.theCuts),
theNEvents(x.theNEvents), position(x.position), reopened(x.reopened),
theMaxScan(x.theMaxScan), scanning(false),
isActive(x.isActive),
theCacheFileName(x.theCacheFileName), doCutEarly(x.doCutEarly),
stats(x.stats), statmap(x.statmap),
thePartonBinInstances(x.thePartonBinInstances),
reweights(x.reweights), preweights(x.preweights),
preweight(x.preweight), reweightPDF(x.reweightPDF),
doInitPDFs(x.doInitPDFs),
theMaxMultCKKW(x.theMaxMultCKKW), theMinMultCKKW(x.theMinMultCKKW),
lastweight(x.lastweight), maxFactor(x.maxFactor),
weightScale(x.weightScale), xSecWeights(x.xSecWeights),
maxWeights(x.maxWeights), skipping(x.skipping),
theMomentumTreatment(x.theMomentumTreatment),
useWeightWarnings(x.useWeightWarnings),
theReOpenAllowed(x.theReOpenAllowed),
theIncludeSpin(x.theIncludeSpin) {}
FxFxReader::~FxFxReader() {}
void FxFxReader::doinitrun() {
HandlerBase::doinitrun();
stats.reset();
for ( StatMap::iterator i = statmap.begin(); i != statmap.end(); ++i )
i->second.reset();
open();
if ( cacheFileName().length() ) openReadCacheFile();
position = 0;
reopened = 0;
}
bool FxFxReader::preInitialize() const {
if ( HandlerBase::preInitialize() ) return true;
if ( doInitPDFs && ! ( inPDF.first && inPDF.second ) ) return true;
return false;
}
void FxFxReader::doinit() {
HandlerBase::doinit();
open();
close();
if ( !heprup.IDBMUP.first || !heprup.IDBMUP.second )
Throw<FxFxInitError>()
<< "No information about incoming particles were found in "
<< "FxFxReader '" << name() << "'." << Exception::warning;
inData = make_pair(getParticleData(heprup.IDBMUP.first),
getParticleData(heprup.IDBMUP.second));
if ( heprup.EBMUP.first <= 0.0 || heprup.EBMUP.second <= 0.0 )
Throw<FxFxInitError>()
<< "No information about the energy of incoming particles were found in "
<< "FxFxReader '" << name() << "'." << Exception::warning;
if ( doInitPDFs && ! ( inPDF.first && inPDF.second ) ) {
initPDFs();
if ( ! ( inPDF.first && inPDF.second ) ) Throw<InitException>()
<< "FxFxReader '" << name()
<< "' could not create PDFBase objects in pre-initialization."
<< Exception::warning;
}
else if ( !inPDF.first || !inPDF.second ) Throw<FxFxInitError>()
<< "No information about the PDFs of incoming particles were found in "
<< "FxFxReader '" << name() << "'." << Exception::warning;
}
void FxFxReader::initPDFs() {
if ( inPDF.first && inPDF.second ) return;
string remhname;
if ( heprup.PDFSUP.first && !inPDF.first) {
inPDF.first = dynamic_ptr_cast<PDFPtr>
(generator()->preinitCreate("ThePEG::LHAPDF", fullName() + "/PDFA",
"ThePEGLHAPDF.so"));
if ( !inPDF.first ) {
Throw<InitException>()
<< "FxFxReader '" << name() << "' could not use information "
<< "about the PDFs used because the LHAPDF library was not properly "
"defined." << Exception::warning;
return;
}
remhname = fullName() + "/DummyRemH";
generator()->preinitCreate("ThePEG::NoRemnants", remhname);
generator()->preinitInterface(inPDF.first, "RemnantHandler",
"set", remhname);
if ( heprup.PDFGUP.first > 0 && heprup.PDFGUP.first < 10 ) {
ostringstream os;
os << heprup.PDFGUP.first << " " << heprup.PDFSUP.first;
generator()->preinitInterface(inPDF.first, "PDFLIBNumbers",
"set", os.str());
} else {
ostringstream os;
os << heprup.PDFGUP.first*1000 + heprup.PDFSUP.first;
generator()->preinitInterface(inPDF.first, "PDFNumber",
"set", os.str());
}
generator()->preinitInterface(inPDF.first, "RangeException",
"newdef", "Freeze");
}
if ( heprup.PDFSUP.second && !inPDF.second) {
inPDF.second = dynamic_ptr_cast<PDFPtr>
(generator()->preinitCreate("ThePEG::LHAPDF", fullName() + "/PDFB",
"ThePEGLHAPDF.so"));
if ( !inPDF.second ) {
Throw<InitException>()
<< "FxFxReader '" << name() << "' could not use information "
<< "about the PDFs used because the LHAPDF library was not properly "
"defined." << Exception::warning;
return;
}
if ( remhname == "" ) {
remhname = fullName() + "/DummyRemH";
generator()->preinitCreate("ThePEG::NoRemnants", remhname);
}
generator()->preinitInterface(inPDF.second, "RemnantHandler",
"set", remhname);
if ( heprup.PDFGUP.second > 0 && heprup.PDFGUP.second < 10 ) {
ostringstream os;
os << heprup.PDFGUP.second << " " << heprup.PDFSUP.second;
generator()->preinitInterface(inPDF.second, "PDFLIBNumbers",
"set", os.str());
} else {
ostringstream os;
os << heprup.PDFGUP.second*1000 + heprup.PDFSUP.second;
generator()->preinitInterface(inPDF.second, "PDFNumber",
"set", os.str());
}
generator()->preinitInterface(inPDF.second, "RangeException",
"newdef", "Freeze");
}
if ( ! ( inPDF.first && inPDF.second ) ) Throw<InitException>()
<< "FxFxReader '" << name()
<< "' could not find information about the PDFs used."
<< Exception::warning;
}
void FxFxReader::initialize(FxFxEventHandler & eh) {
Energy2 Smax = ZERO;
double Y = 0.0;
if ( !theCuts ) {
theCuts = eh.cuts();
if ( !theCuts ) Throw<FxFxInitError>()
<< "No Cuts object was assigned to the FxFxReader '"
<< name() << "' nor was one\nassigned to the controlling "
<< "FxFxEventHandler '" << eh.name() << "'.\nAt least one of them "
<< "needs to have a Cuts object." << Exception::runerror;
Smax = cuts().SMax();
Y = cuts().Y();
}
theCKKW = eh.CKKWHandler();
if ( !partonExtractor() ) {
thePartonExtractor = eh.partonExtractor();
if ( !partonExtractor() ) Throw<FxFxInitError>()
<< "No PartonExtractor object was assigned to the FxFxReader '"
<< name() << "' nor was one\nassigned to the controlling "
<< "FxFxEventHandler '" << eh.name() << "'.\nAt least one of them "
<< "needs to have a PartonExtractor object." << Exception::runerror;
}
open();
Energy emax = 2.0*sqrt(heprup.EBMUP.first*heprup.EBMUP.second)*GeV;
theCuts->initialize(sqr(emax),
0.5*log(heprup.EBMUP.first/heprup.EBMUP.second));
if ( Smax > ZERO && ( Smax != cuts().SMax() || Y != cuts().Y() ) )
Throw<FxFxInitError>()
<< "The FxFxReader '" << name() << "' uses the same Cuts object "
<< "as another FxFxReader which has not got the same energies of "
<< "the colliding particles. For the generation to work properly "
<< "different FxFxReader object with different colliding particles "
<< "must be assigned different (although possibly identical) Cuts "
<< "objects." << Exception::warning;
thePartonBins = partonExtractor()->getPartons(emax, inData, cuts());
for ( int i = 0, N = partonBins().size(); i < N; ++i ) {
theXCombs[partonBins()[i]] =
new_ptr(XComb(emax, inData, &eh, partonExtractor(), CKKWHandler(),
partonBins()[i], theCuts));
partonExtractor()->nDims(partonBins()[i]);
}
outPDF = make_pair(partonExtractor()->getPDF(inData.first),
partonExtractor()->getPDF(inData.second));
close();
if ( !heprup.IDWTUP && useWeightWarnings )
Throw<FxFxInitError>()
<< "No information about the weighting scheme was found. The events "
<< "produced by FxFxReader " << name()
<< " may not be sampled correctly." << Exception::warning;
if ( abs(heprup.IDWTUP) > 1 && !eh.weighted() && useWeightWarnings )
Throw<FxFxInitError>()
<< "FxFxReader " << name() << " has the IDWTUP flag set to "
<< heprup.IDWTUP << " which is not supported by this reader, the "
<< "produced events may not be sampled correctly. It is up to "
<< "sub-classes of FxFxReader to correctly convert to match IDWTUP "
<< "+/- 1. Will try to make intelligent guesses to get "
<< "correct statistics.\nIn most cases this should be sufficient. "
<< "Unset <interface>WeightWarnings</interface> to avoid this message,"
<< "or set <interface>Weighted</interface> to on."
<< Exception::warning;
if ( heprup.IDWTUP != eh.weightOption() && abs(heprup.IDWTUP) < 3 &&
useWeightWarnings )
Throw<FxFxInitError>()
<< "FxFxReader " << name() << " has the IDWTUP flag set to "
<< heprup.IDWTUP
<< ", which does not correspond\nto the weight option "
<< eh.weightOption() << " set in "
<< "the FxFxEventHandler " << eh.name() << ".\n\n"
<< "Use the following handler setting instead:\n"
<< " set " << eh.name() << ":WeightOption " << heprup.IDWTUP
<< "\nWill try to make intelligent guesses to get "
<< "correct statistics. In most cases this should be sufficient. "
<< "Unset <interface>WeightWarnings</interface> to avoid this message"
<< Exception::warning;
scan();
initStat();
}
long FxFxReader::scan() {
open();
// Shall we write the events to a cache file for fast reading? If so
// we write to a temporary file if the caches events should be
// randomized.
if ( cacheFileName().length() ) openWriteCacheFile();
// Keep track of the number of events scanned.
long neve = 0;
long cuteve = 0;
bool negw = false;
// If the open() has not already gotten information about subprocesses
// and cross sections we have to scan through the events.
if ( !heprup.NPRUP || cacheFile() || abs(heprup.IDWTUP) != 1 ) { // why scan if IDWTUP != 1?
HoldFlag<> isScanning(scanning);
- double oldsum = 0.0;
+ // double oldsum = 0.0;
vector<int> lprup;
vector<double> newmax;
vector<long> oldeve;
vector<long> neweve;
vector<double> sumlprup;
vector<double> sumsqlprup;
vector<long> nscanned;
for ( int i = 0; ( maxScan() < 0 || i < maxScan() ) && readEvent(); ++i ) {
if ( !checkPartonBin() ) Throw<FxFxInitError>()
<< "Found event in LesHouchesReader '" << name()
<< "' which cannot be handeled by the assigned PartonExtractor '"
<< partonExtractor()->name() << "'." << Exception::runerror;
vector<int>::iterator idit =
find(lprup.begin(), lprup.end(), hepeup.IDPRUP);
int id = lprup.size();
if ( idit == lprup.end() ) {
lprup.push_back(hepeup.IDPRUP);
newmax.push_back(0.0);
neweve.push_back(0);
oldeve.push_back(0);
sumlprup.push_back(0.);
sumsqlprup.push_back(0.);
nscanned.push_back(0);
} else {
id = idit - lprup.begin();
}
++neve;
++oldeve[id];
- oldsum += hepeup.XWGTUP;
+ // oldsum += hepeup.XWGTUP;
sumlprup[id] += hepeup.XWGTUP;
sumsqlprup[id] += sqr(hepeup.XWGTUP);
++nscanned[id];
if ( cacheFile() ) {
if ( eventWeight() == 0.0 ) {
++cuteve;
continue;
}
cacheEvent();
}
++neweve[id];
newmax[id] = max(newmax[id], abs(eventWeight()));
if ( eventWeight() < 0.0 ) negw = true;
} //end of scanning events
xSecWeights.resize(oldeve.size(), 1.0);
for ( int i = 0, N = oldeve.size(); i < N; ++i )
if ( oldeve[i] ) xSecWeights[i] = double(neweve[i])/double(oldeve[i]);
if ( maxScan() < 0 || neve > NEvents() ) NEvents(neve - cuteve);
if ( lprup.size() == heprup.LPRUP.size() ) {
for ( int id = 0, N = lprup.size(); id < N; ++id ) {
vector<int>::iterator idit =
find(heprup.LPRUP.begin(), heprup.LPRUP.end(), hepeup.IDPRUP);
if ( idit == heprup.LPRUP.end() ) {
Throw<FxFxInitError>()
<< "When scanning events, the LesHouschesReader '" << name()
<< "' found undeclared processes." << Exception::warning;
heprup.NPRUP = 0;
break;
}
int idh = idit - heprup.LPRUP.begin();
heprup.XMAXUP[idh] = newmax[id];
}
}
if ( heprup.NPRUP == 0 ) {
// No heprup block was supplied or something went wrong.
heprup.NPRUP = lprup.size();
heprup.LPRUP.resize(lprup.size());
heprup.XMAXUP.resize(lprup.size());
for ( int id = 0, N = lprup.size(); id < N; ++id ) {
heprup.LPRUP[id] = lprup[id];
heprup.XMAXUP[id] = newmax[id];
}
}
if ( abs(heprup.IDWTUP) != 1 ) {
// Try to fix things if abs(heprup.IDWTUP) != 1.
- double sumxsec = 0.0;
+ // double sumxsec = 0.0;
if(abs(heprup.IDWTUP)==3) {
- for ( int id = 0; id < heprup.NPRUP; ++id ) sumxsec += heprup.XSECUP[id];
+ // for ( int id = 0; id < heprup.NPRUP; ++id ) sumxsec += heprup.XSECUP[id];
}
else {
for ( int id = 0; id < heprup.NPRUP; ++id ) {
//set the cross section directly from the event weights read
heprup.XSECUP[id] = sumlprup[id]/nscanned[id];
heprup.XERRUP[id] = (sumsqlprup[id]/nscanned[id] - sqr(sumlprup[id]/nscanned[id])) / nscanned[id];
if(fabs(heprup.XERRUP[id]) < 1e-10) { heprup.XERRUP[id] = 0; }
if(fabs(newmax[id]) < 1e-10) { newmax[id] = 0; }
if(heprup.XERRUP[id] < 0.) {
if( heprup.XERRUP[id]/(sumsqlprup[id]/nscanned[id])>-1e-10)
heprup.XERRUP[id] = 0.;
else {
Throw<FxFxInitError>()
<< "Negative error when scanning events in LesHouschesReader '" << name()
<< Exception::warning;
heprup.XERRUP[id] = 0.;
}
}
heprup.XERRUP[id] = sqrt( heprup.XERRUP[id] );
heprup.XMAXUP[id] = newmax[id];
//cout << "heprup.XMAXUP[id] = " << heprup.XMAXUP[id] << endl;
- sumxsec += heprup.XSECUP[id];
+ // sumxsec += heprup.XSECUP[id];
}
}
//cout << "sumxsec = " << sumxsec << endl;
//weightScale = picobarn*neve*sumxsec/oldsum;
weightScale = 1.0*picobarn; // temporary fix?
// cout << "weightscale = " << weightScale/picobarn << endl;
}
}
if ( cacheFile() ) closeCacheFile();
if ( negw ) heprup.IDWTUP = min(-abs(heprup.IDWTUP), -1);
return neve;
}
void FxFxReader::setWeightScale(long) {}
void FxFxReader::initStat() {
stats.reset();
statmap.clear();
if ( heprup.NPRUP <= 0 ) return;
double sumx = 0.0;
xSecWeights.resize(heprup.NPRUP, 1.0);
maxWeights.clear();
for ( int ip = 0; ip < heprup.NPRUP; ++ip ) {
sumx = max(heprup.XMAXUP[ip]*xSecWeights[ip], sumx);
statmap[heprup.LPRUP[ip]] =
XSecStat(heprup.XMAXUP[ip]*weightScale*xSecWeights[ip]);
maxWeights[heprup.LPRUP[ip]] = heprup.XMAXUP[ip];
}
stats.maxXSec(sumx*weightScale);
maxFactor = 1.0;
}
void FxFxReader::increaseMaxXSec(CrossSection maxxsec) {
for ( int i = 0; i < heprup.NPRUP; ++i )
statmap[heprup.LPRUP[i]].maxXSec(statmap[heprup.LPRUP[i]].maxXSec()*
maxxsec/stats.maxXSec());
maxFactor *= maxxsec/stats.maxXSec();
stats.maxXSec(maxxsec);
}
tXCombPtr FxFxReader::getXComb() {
if ( lastXCombPtr() ) return lastXCombPtr();
fillEvent();
connectMothers();
tcPBPair sel = createPartonBinInstances();
tXCombPtr lastXC = xCombs()[sel];
// clean up the old XComb object before switching to a new one
if ( theLastXComb && theLastXComb != lastXC )
theLastXComb->clean();
theLastXComb = lastXC;
lastXCombPtr()->subProcess(SubProPtr());
lastXCombPtr()->setPartonBinInstances(partonBinInstances(),
sqr(hepeup.SCALUP)*GeV2);
lastXCombPtr()->lastAlphaS(hepeup.AQCDUP);
lastXCombPtr()->lastAlphaEM(hepeup.AQEDUP);
return lastXCombPtr();
}
tSubProPtr FxFxReader::getSubProcess() {
getXComb();
if ( subProcess() ) return subProcess();
lastXCombPtr()->subProcess(new_ptr(SubProcess(lastPartons(), tCollPtr(), this)));
subProcess()->setOutgoing(outgoing().begin(), outgoing().end());
subProcess()->setIntermediates(intermediates().begin(),
intermediates().end());
return subProcess();
}
void FxFxReader::fillEvent() {
if ( !particleIndex.empty() ) return;
particleIndex.clear();
colourIndex.clear();
colourIndex(0, tColinePtr());
createParticles();
createBeams();
}
void FxFxReader::reopen() {
// If we didn't know how many events there were, we know now.
if ( NEvents() <= 0 ) NEvents(position);
++reopened;
// How large fraction of the events have we actually used? And how
// large will we have used if we go through the file again?
double frac = double(stats.attempts())/double(NEvents());
if ( frac*double(reopened + 1)/double(reopened) > 1.0 &&
NEvents() - stats.attempts() <
generator()->N() - generator()->currentEventNumber() ) {
if(theReOpenAllowed)
generator()->logWarning(FxFxReopenWarning()
<< "Reopening FxFxReader '" << name()
<< "' after accessing " << stats.attempts()
<< " events out of "
<< NEvents() << Exception::warning);
else
throw FxFxReopenWarning()
<< "More events requested than available in FxFxReader "
<< name() << Exception::runerror;
}
if ( cacheFile() ) {
closeCacheFile();
openReadCacheFile();
if ( !uncacheEvent() ) Throw<FxFxReopenError>()
<< "Could not reopen FxFxReader '" << name()
<< "'." << Exception::runerror;
} else {
close();
open();
if ( !readEvent() ) Throw<FxFxReopenError>()
<< "Could not reopen FxFxReader '" << name()
<< "'." << Exception::runerror;
}
}
void FxFxReader::reset() {
particleIndex.clear();
colourIndex.clear();
if ( theLastXComb ) theLastXComb->clean();
theLastXComb = tXCombPtr();
}
bool FxFxReader::readEvent() {
reset();
if ( !doReadEvent() ) return false;
// If we are just skipping event we do not need to reweight or do
// anything fancy.
if ( skipping ) return true;
if ( cacheFile() && !scanning ) return true;
// Reweight according to the re- and pre-weights objects in the
// FxFxReader base class.
lastweight = reweight();
if ( !reweightPDF && !cutEarly() ) return true;
// We should try to reweight the PDFs or make early cuts here.
fillEvent();
double x1 = incoming().first->momentum().plus()/
beams().first->momentum().plus();
if ( reweightPDF &&
inPDF.first && outPDF.first && inPDF.first != outPDF.first ) {
if ( hepeup.XPDWUP.first <= 0.0 )
hepeup.XPDWUP.first =
inPDF.first->xfx(inData.first, incoming().first->dataPtr(),
sqr(hepeup.SCALUP*GeV), x1);
double xf = outPDF.first->xfx(inData.first, incoming().first->dataPtr(),
sqr(hepeup.SCALUP*GeV), x1);
lastweight *= xf/hepeup.XPDWUP.first;
hepeup.XPDWUP.first = xf;
}
double x2 = incoming().second->momentum().minus()/
beams().second->momentum().minus();
if ( reweightPDF &&
inPDF.second && outPDF.second && inPDF.second != outPDF.second ) {
if ( hepeup.XPDWUP.second <= 0.0 )
hepeup.XPDWUP.second =
inPDF.second->xfx(inData.second, incoming().second->dataPtr(),
sqr(hepeup.SCALUP*GeV), x2);
double xf =
outPDF.second->xfx(inData.second, incoming().second->dataPtr(),
sqr(hepeup.SCALUP*GeV), x2);
lastweight *= xf/hepeup.XPDWUP.second;
hepeup.XPDWUP.second = xf;
}
if ( cutEarly() ) {
if ( !cuts().initSubProcess((incoming().first->momentum() +
incoming().second->momentum()).m2(),
0.5*log(x1/x2)) ) lastweight = 0.0;
tSubProPtr sub = getSubProcess();
TmpTransform<tSubProPtr> tmp(sub, Utilities::getBoostToCM(sub->incoming()));
if ( !cuts().passCuts(*sub) ) lastweight = 0.0;
}
return true;
}
double FxFxReader::getEvent() {
if ( cacheFile() ) {
if ( !uncacheEvent() ) reopen();
} else {
if ( !readEvent() ) reopen();
}
++position;
double max = maxWeights[hepeup.IDPRUP]*maxFactor;
// cout << "maxFactor = " << maxFactor << " maxWeights[hepeup.IDPRUP] = " << maxWeights[hepeup.IDPRUP] << endl;
// normalize all the weights to the max weight
for(map<string,double>::iterator it=optionalWeights.begin();
it!=optionalWeights.end();++it) {
if(it->first!="ecom" && it->second!=-999 && it->second!=-111 && it->second!=-222 && it->second!=-333) {
it->second = (max != 0.0) ? it->second/max : 0.0;
}
}
//cout << "hepeup.XWGTUP = " << hepeup.XWGTUP << endl;
//cout << "max = " << max << " " << eventWeight() << endl;
return max != 0.0? eventWeight()/max: 0.0;
}
void FxFxReader::skip(long n) {
HoldFlag<> skipflag(skipping);
while ( n-- ) getEvent();
}
double FxFxReader::reweight() {
preweight = 1.0;
if ( reweights.empty() && preweights.empty() &&
!( CKKWHandler() && maxMultCKKW() > 0 && maxMultCKKW() > minMultCKKW() ) )
return 1.0;
fillEvent();
getSubProcess();
for ( int i = 0, N = preweights.size(); i < N; ++i ) {
preweights[i]->setXComb(lastXCombPtr());
preweight *= preweights[i]->weight();
}
double weight = preweight;
for ( int i = 0, N = reweights.size(); i < N; ++i ) {
reweights[i]->setXComb(lastXCombPtr());
weight *= reweights[i]->weight();
}
// If we are caching events we do not want to do CKKW reweighting.
if ( cacheFile() ) return weight;
if ( CKKWHandler() && maxMultCKKW() > 0 && maxMultCKKW() > minMultCKKW() ) {
CKKWHandler()->setXComb(lastXCombPtr());
weight *= CKKWHandler()->reweightCKKW(minMultCKKW(), maxMultCKKW());
}
return weight;
}
bool FxFxReader::checkPartonBin() {
// First find the positions of the incoming partons.
pair< vector<int>, vector<int> > inc;
for ( int i = 0; i < hepeup.NUP; ++i ) {
if ( hepeup.ISTUP[i] == -9 ) {
if ( inc.first.empty() ) inc.first.push_back(i);
else if ( inc.second.empty() ) inc.second.push_back(i);
}
else if ( hepeup.ISTUP[i] == -1 ) {
if ( inc.first.size() &&
hepeup.MOTHUP[i].first == inc.first.back() + 1 )
inc.first.push_back(i);
else if ( inc.second.size() &&
hepeup.MOTHUP[i].first == inc.second.back() + 1 )
inc.second.push_back(i);
else if ( inc.first.empty() ) {
inc.first.push_back(-1);
inc.first.push_back(i);
}
else if ( inc.second.empty() ) {
inc.second.push_back(-1);
inc.second.push_back(i);
}
else if ( inc.first.size() <= inc.second.size() )
inc.first.push_back(i);
else
inc.second.push_back(i);
}
}
// Now store the corresponding id numbers
pair< vector<long>, vector<long> > ids;
ids.first.push_back(inc.first[0] < 0? heprup.IDBMUP.first:
hepeup.IDUP[inc.first[0]]);
for ( int i = 1, N = inc.first.size(); i < N; ++i )
ids.first.push_back(hepeup.IDUP[inc.first[i]]);
ids.second.push_back(inc.second[0] < 0? heprup.IDBMUP.second:
hepeup.IDUP[inc.second[0]]);
for ( int i = 1, N = inc.second.size(); i < N; ++i )
ids.second.push_back(hepeup.IDUP[inc.second[i]]);
// Find the correct pair of parton bins.
PBPair pbp;
for ( int i = 0, N = partonBins().size(); i < N; ++i ) {
tcPBPtr curr = partonBins()[i].first;
int icurr = inc.first.size() - 1;
while ( curr && icurr >= 0 ) {
if ( curr->parton()->id () != ids.first[icurr] ) break;
curr = curr->incoming();
--icurr;
}
if(!(!partonBins()[i].first->incoming() &&
!partonBins()[i].first->particle() &&
partonBins()[i].first->parton()->id () == ids.first[0] &&
( inc.first.size()==1 ||
(inc.first.size()==2 && ids.first[0]==ids.first[1]))) &&
( curr || icurr >= 0 ) ) continue;
curr = partonBins()[i].second;
icurr = inc.second.size() - 1;
while ( curr && icurr >= 0 ) {
if ( curr->parton()->id () != ids.second[icurr] ) break;
curr = curr->incoming();
--icurr;
}
if(!(!partonBins()[i].second->incoming() &&
!partonBins()[i].second->particle() &&
partonBins()[i].second->parton()->id () == ids.second[0] &&
( inc.second.size()==1 ||
(inc.second.size()==2 && ids.second[0]==ids.second[1]))) &&
( curr || icurr >= 0 ) ) continue;
pbp = partonBins()[i];
}
// If we are only checking we return here.
return ( pbp.first && pbp.second );
}
namespace {
bool recursionNotNull(tcPBPtr bin, tcPPtr p) {
while ( bin && p ) {
if ( p->dataPtr() != bin->parton() ) break;
bin = bin->incoming();
p = p->parents().size()? p->parents()[0]: tPPtr();
}
return bin || p;
}
}
tcPBPair FxFxReader::createPartonBinInstances() {
tcPBPair sel;
for ( int i = 0, N = partonBins().size(); i < N; ++i ) {
tcPBPtr bin = partonBins()[i].first;
tcPPtr p = incoming().first;
if ( recursionNotNull(bin,p) ) continue;
bin = partonBins()[i].second;
p = incoming().second;
if ( recursionNotNull(bin,p) ) continue;
sel = partonBins()[i];
break;
}
if ( !sel.first || !sel.second ) Throw<FxFxInconsistencyError>()
<< "Could not find appropriate PartonBin objects for event produced by "
<< "FxFxReader '" << name() << "'." << Exception::runerror;
Direction<0> dir(true);
thePartonBinInstances.first =
new_ptr(PartonBinInstance(incoming().first, sel.first,
-sqr(hepeup.SCALUP*GeV)));
if ( thePartonBinInstances.first->xi() > 1.00001 ) {
Throw<FxFxInconsistencyError>()
<< "Found an event with momentum fraction larger than unity (x1="
<< thePartonBinInstances.first->xi()
<< "). The event will be skipped." << Exception::warning;
throw Veto();
}
dir.reverse();
thePartonBinInstances.second =
new_ptr(PartonBinInstance(incoming().second, sel.second,
-sqr(hepeup.SCALUP*GeV)));
if ( thePartonBinInstances.second->xi() > 1.00001 ) {
Throw<FxFxInconsistencyError>()
<< "Found an event with momentum fraction larger than unity (x2="
<< thePartonBinInstances.second->xi()
<< "). The event will be skipped." << Exception::warning;
throw Veto();
}
return sel;
}
void FxFxReader::createParticles() {
theBeams = PPair();
theIncoming = PPair();
theOutgoing = PVector();
theIntermediates = PVector();
for ( int i = 0, N = hepeup.IDUP.size(); i < N; ++i ) {
if ( !hepeup.IDUP[i] ) continue;
Lorentz5Momentum mom(hepeup.PUP[i][0]*GeV, hepeup.PUP[i][1]*GeV,
hepeup.PUP[i][2]*GeV, hepeup.PUP[i][3]*GeV,
hepeup.PUP[i][4]*GeV);
if(theMomentumTreatment == 1) mom.rescaleEnergy();
else if(theMomentumTreatment == 2) mom.rescaleMass();
PDPtr pd = getParticleData(hepeup.IDUP[i]);
if (!pd) {
Throw<FxFxInitError>()
<< "FxFxReader '" << name() << "' found unknown particle ID "
<< hepeup.IDUP[i]
<< " in Les Houches common block structure.\n"
<< "You need to define the new particle in an input file.\n"
<< Exception::runerror;
}
if ( ! pd->coloured()
&& ( hepeup.ICOLUP[i].first != 0 || hepeup.ICOLUP[i].second != 0 ) ) {
Throw<FxFxInconsistencyError>()
<< "FxFxReader " << name() << ": " << pd->PDGName()
<< " is not a coloured particle.\nIt should not have "
<< "(anti-)colour lines " << hepeup.ICOLUP[i].first
<< ' ' << hepeup.ICOLUP[i].second
<< " set; the event file needs to be fixed."
<< Exception::runerror;
}
PPtr p = pd->produceParticle(mom);
if(hepeup.ICOLUP[i].first>=0 && hepeup.ICOLUP[i].second >=0) {
tColinePtr c = colourIndex(hepeup.ICOLUP[i].first);
if ( c ) c->addColoured(p);
c = colourIndex(hepeup.ICOLUP[i].second);
if ( c ) c->addAntiColoured(p);
}
else {
tColinePtr c1 = colourIndex(abs(hepeup.ICOLUP[i].first ));
tColinePtr c2 = colourIndex(abs(hepeup.ICOLUP[i].second));
if(pd->hasColour()) {
c1->addColouredIndexed(p,1);
c2->addColouredIndexed(p,2);
}
else {
c1->addAntiColouredIndexed(p,1);
c2->addAntiColouredIndexed(p,2);
}
}
particleIndex(i + 1, p);
switch ( hepeup.ISTUP[i] ) {
case -9:
if ( !theBeams.first ) theBeams.first = p;
else if ( !theBeams.second ) theBeams.second = p;
else Throw<FxFxInconsistencyError>()
<< "To many incoming beam particles in the FxFxReader '"
<< name() << "'." << Exception::runerror;
break;
case -1:
if ( !theIncoming.first ) theIncoming.first = p;
else if ( !theIncoming.second ) theIncoming.second = p;
else if ( particleIndex(theIncoming.first) == hepeup.MOTHUP[i].first )
theIncoming.first = p;
else if ( particleIndex(theIncoming.second) == hepeup.MOTHUP[i].first )
theIncoming.second = p;
else Throw<FxFxInconsistencyError>()
<< "To many incoming particles to hard subprocess in the "
<< "FxFxReader '" << name() << "'." << Exception::runerror;
p->scale(sqr(hepeup.SCALUP*GeV));
break;
case 1:
theOutgoing.push_back(p);
p->scale(sqr(hepeup.SCALUP*GeV));
break;
case -2:
case 2:
case 3:
theIntermediates.push_back(p);
break;
default:
Throw<FxFxInconsistencyError>()
<< "Unknown status code (" << hepeup.ISTUP[i]
<< ") in the FxFxReader '" << name() << "'."
<< Exception::runerror;
}
// value 9 is defined as "Unknown or unpolarized particles"
double spinup = hepeup.SPINUP[i];
if ( abs(spinup - 9) < 1.0e-3 )
spinup = 0.;
if ( spinup < -1. || spinup > 1. ) {
Throw<FxFxInconsistencyError>()
<< "Polarization must be between -1 and 1, not "
<< spinup << " as found in the "
<< "FxFx event file.\nThe event file needs to be fixed."
<< Exception::runerror;
}
if( theIncludeSpin
&& abs(pd->id()) == ParticleID::tauminus
&& spinup !=0) {
if(pd->iSpin() == PDT::Spin1Half ) {
vector<Helicity::SpinorWaveFunction> wave;
Helicity::SpinorWaveFunction(wave,p,Helicity::outgoing,true);
RhoDMatrix rho(pd->iSpin(),true);
rho(0,0) = 0.5*(1.-spinup);
rho(1,1) = 0.5*(1.+spinup);
p->spinInfo()->rhoMatrix() = rho;
p->spinInfo()-> DMatrix() = rho;
}
}
}
// check the colour flows, and if necessary create any sources/sinks
// hard process
// get the particles in the hard process
PVector external;
for ( int i = 0, N = hepeup.IDUP.size(); i < N; ++i ) {
unsigned int moth;
switch ( hepeup.ISTUP[i] ) {
case -1:
external.push_back(particleIndex.find(i+1));
break;
case 1: case 2: case 3:
moth = hepeup.MOTHUP[i].first;
if(moth!=0 && (hepeup.ISTUP[moth]==-1||hepeup.ISTUP[moth]==-2||
hepeup.ISTUP[moth]==-9))
external.push_back(particleIndex.find(i+1));
moth = hepeup.MOTHUP[i].second;
if(moth!=0 && (hepeup.ISTUP[moth]==-1||hepeup.ISTUP[moth]==-2||
hepeup.ISTUP[moth]==-9))
external.push_back(particleIndex.find(i+1));
break;
case -2: case -9: default:
break;
}
}
// check the incoming/outgoing lines match
vector<tColinePtr> unMatchedColour,unMatchedAntiColour;
for(unsigned int ix=0;ix<external.size();++ix) {
vector<tcColinePtr>
col = external[ix]->colourInfo()-> colourLines();
vector<tcColinePtr>
anti = external[ix]->colourInfo()->antiColourLines();
if(hepeup.ISTUP[particleIndex(external[ix])-1]<0)
swap(col,anti);
if(!col.empty()) {
for(unsigned int ic1=0;ic1<col.size();++ic1) {
bool matched=false;
for(unsigned int iy=0;iy<external.size();++iy) {
if(iy==ix) continue;
vector<tcColinePtr> col2;
if(hepeup.ISTUP[particleIndex(external[iy])-1]<0) {
if(external[iy]->colourInfo()->colourLines().empty()) continue;
col2 = external[iy]->colourInfo()->colourLines();
}
else if(hepeup.ISTUP[particleIndex(external[iy])-1]>0) {
if(external[iy]->colourInfo()->antiColourLines().empty()) continue;
col2 = external[iy]->colourInfo()->antiColourLines();
}
for(unsigned int ic2=0;ic2<col2.size();++ic2) {
if(col[ic1]==col2[ic2]) {
matched=true;
break;
}
}
if(matched) break;
}
if(!matched) unMatchedColour.push_back(const_ptr_cast<tColinePtr>(col[ic1]));
}
}
if(!anti.empty()) {
for(unsigned int ic1=0;ic1<anti.size();++ic1) {
bool matched=false;
for(unsigned int iy=0;iy<external.size();++iy) {
if(iy==ix) continue;
vector<tcColinePtr> anti2;
if(hepeup.ISTUP[particleIndex(external[iy])-1]<0) {
if(external[iy]->colourInfo()->antiColourLines().empty()) continue;
anti2 = external[iy]->colourInfo()->antiColourLines();
}
else if(hepeup.ISTUP[particleIndex(external[iy])-1]>0) {
if(external[iy]->colourInfo()->colourLines().empty()) continue;
anti2 = external[iy]->colourInfo()->colourLines();
}
for(unsigned int ic2=0;ic2<anti2.size();++ic2) {
if(anti[ic1]==anti2[ic2]) {
matched=true;
break;
}
}
if(matched) break;
}
if(!matched) unMatchedAntiColour.push_back(const_ptr_cast<tColinePtr>(anti[ic1]));
}
}
}
// might have source/sink
if( unMatchedColour.size() + unMatchedAntiColour.size() != 0) {
if(unMatchedColour.size() == 3 ) {
unMatchedColour[0]->setSourceNeighbours(unMatchedColour[1],
unMatchedColour[2]);
}
else if(unMatchedColour.size() != 0 && ThePEG_DEBUG_LEVEL) {
Throw<FxFxInconsistencyError>()
<< "FxFxReader '" << name() << "' found inconsistent colour "
<< "flow in Les Houches common block structure for hard process.\n"
<< hepeup << Exception::runerror;
}
if(unMatchedAntiColour.size() == 3 ) {
unMatchedAntiColour[0]->setSinkNeighbours(unMatchedAntiColour[1],
unMatchedAntiColour[2]);
}
else if(unMatchedAntiColour.size() != 0 && ThePEG_DEBUG_LEVEL) {
Throw<FxFxInconsistencyError>()
<< "FxFxReader '" << name() << "' found inconsistent colour "
<< "flow in Les Houches common block structure for hard process.\n"
<< hepeup << Exception::runerror;
}
}
// any subsequent decays
for ( int i = 0, N = hepeup.IDUP.size(); i < N; ++i ) {
if(hepeup.ISTUP[i] !=2 && hepeup.ISTUP[i] !=3) continue;
PVector external;
external.push_back(particleIndex.find(i+1));
for ( int j = 0; j < N; ++j ) {
if(hepeup.MOTHUP[j].first==i+1|| hepeup.MOTHUP[j].second==i+1)
external.push_back(particleIndex.find(j+1));
}
// check the incoming/outgoing lines match
vector<tColinePtr> unMatchedColour,unMatchedAntiColour;
for(unsigned int ix=0;ix<external.size();++ix) {
vector<tcColinePtr>
col = external[ix]->colourInfo()-> colourLines();
vector<tcColinePtr>
anti = external[ix]->colourInfo()->antiColourLines();
if(ix==0) swap(col,anti);
if(!col.empty()) {
for(unsigned int ic1=0;ic1<col.size();++ic1) {
bool matched=false;
for(unsigned int iy=0;iy<external.size();++iy) {
if(iy==ix) continue;
vector<tcColinePtr> col2;
if(iy==0) {
if(external[iy]->colourInfo()->colourLines().empty()) continue;
col2 = external[iy]->colourInfo()->colourLines();
}
else {
if(external[iy]->colourInfo()->antiColourLines().empty()) continue;
col2 = external[iy]->colourInfo()->antiColourLines();
}
for(unsigned int ic2=0;ic2<col2.size();++ic2) {
if(col[ic1]==col2[ic2]) {
matched=true;
break;
}
}
if(matched) break;
}
if(!matched) unMatchedColour.push_back(const_ptr_cast<tColinePtr>(col[ic1]));
}
}
if(!anti.empty()) {
for(unsigned int ic1=0;ic1<anti.size();++ic1) {
bool matched=false;
for(unsigned int iy=0;iy<external.size();++iy) {
if(iy==ix) continue;
vector<tcColinePtr> anti2;
if(iy==0) {
if(external[iy]->colourInfo()->antiColourLines().empty()) continue;
anti2 = external[iy]->colourInfo()->antiColourLines();
}
else {
if(external[iy]->colourInfo()->colourLines().empty()) continue;
anti2 = external[iy]->colourInfo()->colourLines();
}
for(unsigned int ic2=0;ic2<anti2.size();++ic2) {
if(anti[ic1]==anti2[ic2]) {
matched=true;
break;
}
}
if(matched) break;
}
if(!matched) unMatchedAntiColour.push_back(const_ptr_cast<tColinePtr>(anti[ic1]));
}
}
}
// might have source/sink
if( unMatchedColour.size() + unMatchedAntiColour.size() != 0) {
if(unMatchedColour.size() == 3 ) {
unMatchedColour[0]->setSourceNeighbours(unMatchedColour[1],
unMatchedColour[2]);
}
else if(unMatchedColour.size() != 0 && ThePEG_DEBUG_LEVEL) {
Throw<FxFxInconsistencyError>()
<< "FxFxReader '" << name() << "' found inconsistent colour "
<< "flow in Les Houches common block structure for decay of \n"
<< *external[0] << "\n"
<< hepeup << Exception::runerror;
}
if(unMatchedAntiColour.size() == 3 ) {
unMatchedAntiColour[0]->setSinkNeighbours(unMatchedAntiColour[1],
unMatchedAntiColour[2]);
}
else if(unMatchedAntiColour.size() != 0 && ThePEG_DEBUG_LEVEL) {
Throw<FxFxInconsistencyError>()
<< "FxFxReader '" << name() << "' found inconsistent colour "
<< "flow in Les Houches common block structure for decay of\n"
<< *external[0] << "\n"
<< hepeup << Exception::runerror;
}
}
}
}
void FxFxReader::createBeams() {
if ( !theBeams.first && dynamic_ptr_cast<Ptr<NoPDF>::tcp>(inPDF.first) ) {
theBeams.first = theIncoming.first;
}
else if ( !theBeams.first ) {
theBeams.first = getParticleData(heprup.IDBMUP.first)->produceParticle();
double m = theBeams.first->mass()/GeV;
theBeams.first->set5Momentum
(Lorentz5Momentum(ZERO, ZERO,
sqrt(sqr(heprup.EBMUP.first) - sqr(m))*GeV,
heprup.EBMUP.first*GeV, m*GeV));
hepeup.IDUP.push_back(heprup.IDBMUP.first);
hepeup.ISTUP.push_back(-9);
hepeup.MOTHUP.push_back(make_pair(0, 0));
hepeup.ICOLUP.push_back(make_pair(0, 0));
hepeup.VTIMUP.push_back(0.0);
hepeup.SPINUP.push_back(0.0);
particleIndex(hepeup.IDUP.size(), theBeams.first);
hepeup.MOTHUP[particleIndex(theIncoming.first) - 1].first =
hepeup.IDUP.size();
}
if ( !theBeams.second && dynamic_ptr_cast<Ptr<NoPDF>::tcp>(inPDF.second) ) {
theBeams.second = theIncoming.second;
}
else if ( !theBeams.second ) {
theBeams.second = getParticleData(heprup.IDBMUP.second)->produceParticle();
double m = theBeams.second->mass()/GeV;
theBeams.second->set5Momentum
(Lorentz5Momentum(ZERO, ZERO,
-sqrt(sqr(heprup.EBMUP.second) - sqr(m))*GeV,
heprup.EBMUP.second*GeV, m*GeV));
hepeup.IDUP.push_back(heprup.IDBMUP.second);
hepeup.ISTUP.push_back(-9);
hepeup.MOTHUP.push_back(make_pair(0, 0));
hepeup.ICOLUP.push_back(make_pair(0, 0));
hepeup.VTIMUP.push_back(0.0);
hepeup.SPINUP.push_back(0.0);
particleIndex(hepeup.IDUP.size(), theBeams.second);
hepeup.MOTHUP[particleIndex(theIncoming.second) - 1].first =
hepeup.IDUP.size();
}
}
void FxFxReader::connectMothers() {
const ObjectIndexer<long,Particle> & pi = particleIndex;
for ( int i = 0, N = hepeup.IDUP.size(); i < N; ++i ) {
if ( pi(hepeup.MOTHUP[i].first) )
pi(hepeup.MOTHUP[i].first)->addChild(pi(i + 1));
if ( pi(hepeup.MOTHUP[i].second)
&& hepeup.MOTHUP[i].second != hepeup.MOTHUP[i].first )
pi(hepeup.MOTHUP[i].second)->addChild(pi(i + 1));
}
}
void FxFxReader::openReadCacheFile() {
if ( cacheFile() ) closeCacheFile();
cacheFile().open(cacheFileName(), "r");
position = 0;
}
void FxFxReader::openWriteCacheFile() {
if ( cacheFile() ) closeCacheFile();
cacheFile().open(cacheFileName(), "w");
}
void FxFxReader::closeCacheFile() {
cacheFile().close();
}
void FxFxReader::cacheEvent() const {
static vector<char> buff;
cacheFile().write(&hepeup.NUP, sizeof(hepeup.NUP));
buff.resize(eventSize(hepeup.NUP));
char * pos = &buff[0];
pos = mwrite(pos, hepeup.IDPRUP);
pos = mwrite(pos, hepeup.XWGTUP);
pos = mwrite(pos, hepeup.XPDWUP);
pos = mwrite(pos, hepeup.SCALUP);
pos = mwrite(pos, hepeup.AQEDUP);
pos = mwrite(pos, hepeup.AQCDUP);
pos = mwrite(pos, hepeup.IDUP[0], hepeup.NUP);
pos = mwrite(pos, hepeup.ISTUP[0], hepeup.NUP);
pos = mwrite(pos, hepeup.MOTHUP[0], hepeup.NUP);
pos = mwrite(pos, hepeup.ICOLUP[0], hepeup.NUP);
for ( int i = 0; i < hepeup.NUP; ++i )
pos = mwrite(pos, hepeup.PUP[i][0], 5);
pos = mwrite(pos, hepeup.VTIMUP[0], hepeup.NUP);
pos = mwrite(pos, hepeup.SPINUP[0], hepeup.NUP);
pos = mwrite(pos, lastweight);
pos = mwrite(pos, optionalWeights);
pos = mwrite(pos, LHEeventnum);
for(size_t ff = 0; ff < optionalWeightsNames.size(); ff++) {
pos = mwrite(pos, optionalWeightsNames[ff]);
}
/* for(int f = 0; f < optionalWeightsNames.size(); f++) {
cout << "optionalWeightsNames = " << optionalWeightsNames[f] << endl;
}*/
pos = mwrite(pos, optionalnpLO);
pos = mwrite(pos, optionalnpNLO);
pos = mwrite(pos, preweight);
cacheFile().write(&buff[0], buff.size(), 1);
}
bool FxFxReader::uncacheEvent() {
reset();
static vector<char> buff;
if ( cacheFile().read(&hepeup.NUP, sizeof(hepeup.NUP)) != 1 )
return false;
buff.resize(eventSize(hepeup.NUP));
if ( cacheFile().read(&buff[0], buff.size()) != 1 ) return false;
const char * pos = &buff[0];
pos = mread(pos, hepeup.IDPRUP);
pos = mread(pos, hepeup.XWGTUP);
pos = mread(pos, hepeup.XPDWUP);
pos = mread(pos, hepeup.SCALUP);
pos = mread(pos, hepeup.AQEDUP);
pos = mread(pos, hepeup.AQCDUP);
hepeup.IDUP.resize(hepeup.NUP);
pos = mread(pos, hepeup.IDUP[0], hepeup.NUP);
hepeup.ISTUP.resize(hepeup.NUP);
pos = mread(pos, hepeup.ISTUP[0], hepeup.NUP);
hepeup.MOTHUP.resize(hepeup.NUP);
pos = mread(pos, hepeup.MOTHUP[0], hepeup.NUP);
hepeup.ICOLUP.resize(hepeup.NUP);
pos = mread(pos, hepeup.ICOLUP[0], hepeup.NUP);
hepeup.PUP.resize(hepeup.NUP);
for ( int i = 0; i < hepeup.NUP; ++i )
pos = mread(pos, hepeup.PUP[i][0], 5);
hepeup.VTIMUP.resize(hepeup.NUP);
pos = mread(pos, hepeup.VTIMUP[0], hepeup.NUP);
hepeup.SPINUP.resize(hepeup.NUP);
pos = mread(pos, hepeup.SPINUP[0], hepeup.NUP);
pos = mread(pos, lastweight);
pos = mread(pos, optionalWeights);
for(size_t ff = 0; ff < optionalWeightsNames.size(); ff++) {
pos = mread(pos, optionalWeightsNames[ff]);
}
pos = mread(pos, optionalnpLO);
pos = mread(pos, optionalnpNLO);
pos = mread(pos, preweight);
pos = mread(pos, LHEeventnum);
// If we are skipping, we do not have to do anything else.
if ( skipping ) return true;
if ( CKKWHandler() && maxMultCKKW() > 0 && maxMultCKKW() > minMultCKKW() ) {
// The cached event has not been submitted to CKKW reweighting, so
// we do that now.
fillEvent();
getSubProcess();
CKKWHandler()->setXComb(lastXCombPtr());
lastweight *= CKKWHandler()->reweightCKKW(minMultCKKW(), maxMultCKKW());
}
return true;
}
void FxFxReader::persistentOutput(PersistentOStream & os) const {
os << heprup.IDBMUP << heprup.EBMUP << heprup.PDFGUP << heprup.PDFSUP
<< heprup.IDWTUP << heprup.NPRUP << heprup.XSECUP << heprup.XERRUP
<< heprup.XMAXUP << heprup.LPRUP << hepeup.NUP << hepeup.IDPRUP
<< hepeup.XWGTUP << hepeup.XPDWUP << hepeup.SCALUP << hepeup.AQEDUP
<< hepeup.AQCDUP << hepeup.IDUP << hepeup.ISTUP << hepeup.MOTHUP
<< hepeup.ICOLUP << hepeup.PUP << hepeup.VTIMUP << hepeup.SPINUP
<< inData << inPDF << outPDF << thePartonExtractor << theCKKW
<< thePartonBins << theXCombs << theCuts << theNEvents << position
<< reopened << theMaxScan << isActive
<< theCacheFileName << doCutEarly << stats << statmap
<< thePartonBinInstances
<< theBeams << theIncoming << theOutgoing << theIntermediates
<< reweights << preweights << preweight << reweightPDF << doInitPDFs
<< theLastXComb << theMaxMultCKKW << theMinMultCKKW << lastweight << optionalWeights << optionalnpLO << optionalnpNLO << LHEeventnum
<< maxFactor << ounit(weightScale, picobarn) << xSecWeights << maxWeights
<< theMomentumTreatment << useWeightWarnings << theReOpenAllowed
<< theIncludeSpin;
}
void FxFxReader::persistentInput(PersistentIStream & is, int) {
if ( cacheFile() ) closeCacheFile();
is >> heprup.IDBMUP >> heprup.EBMUP >> heprup.PDFGUP >> heprup.PDFSUP
>> heprup.IDWTUP >> heprup.NPRUP >> heprup.XSECUP >> heprup.XERRUP
>> heprup.XMAXUP >> heprup.LPRUP >> hepeup.NUP >> hepeup.IDPRUP
>> hepeup.XWGTUP >> hepeup.XPDWUP >> hepeup.SCALUP >> hepeup.AQEDUP
>> hepeup.AQCDUP >> hepeup.IDUP >> hepeup.ISTUP >> hepeup.MOTHUP
>> hepeup.ICOLUP >> hepeup.PUP >> hepeup.VTIMUP >> hepeup.SPINUP
>> inData >> inPDF >> outPDF >> thePartonExtractor >> theCKKW
>> thePartonBins >> theXCombs >> theCuts >> theNEvents >> position
>> reopened >> theMaxScan >> isActive
>> theCacheFileName >> doCutEarly >> stats >> statmap
>> thePartonBinInstances
>> theBeams >> theIncoming >> theOutgoing >> theIntermediates
>> reweights >> preweights >> preweight >> reweightPDF >> doInitPDFs
>> theLastXComb >> theMaxMultCKKW >> theMinMultCKKW >> lastweight >> optionalWeights >> optionalnpLO >> optionalnpNLO >> LHEeventnum
>> maxFactor >> iunit(weightScale, picobarn) >> xSecWeights >> maxWeights
>> theMomentumTreatment >> useWeightWarnings >> theReOpenAllowed
>> theIncludeSpin;
}
AbstractClassDescription<FxFxReader>
FxFxReader::initFxFxReader;
// Definition of the static class description member.
void FxFxReader::setBeamA(long id) { heprup.IDBMUP.first = id; }
long FxFxReader::getBeamA() const { return heprup.IDBMUP.first; }
void FxFxReader::setBeamB(long id) { heprup.IDBMUP.second = id; }
long FxFxReader::getBeamB() const { return heprup.IDBMUP.second; }
void FxFxReader::setEBeamA(Energy e) { heprup.EBMUP.first = e/GeV; }
Energy FxFxReader::getEBeamA() const { return heprup.EBMUP.first*GeV; }
void FxFxReader::setEBeamB(Energy e) { heprup.EBMUP.second = e/GeV; }
Energy FxFxReader::getEBeamB() const { return heprup.EBMUP.second*GeV; }
void FxFxReader::setPDFA(PDFPtr pdf) { inPDF.first = pdf; }
PDFPtr FxFxReader::getPDFA() const { return inPDF.first; }
void FxFxReader::setPDFB(PDFPtr pdf) { inPDF.second = pdf; }
PDFPtr FxFxReader::getPDFB() const { return inPDF.second; }
void FxFxReader::Init() {
static ClassDocumentation<FxFxReader> documentation
("ThePEG::FxFxReader is an abstract base class to be used "
"for objects which reads event files or streams from matrix element "
"generators.");
static Parameter<FxFxReader,long> interfaceBeamA
("BeamA",
"The PDG id of the incoming particle along the positive z-axis. "
"If zero the corresponding information is to be deduced from the "
"event stream/file.",
0, 0, 0, 0,
true, false, false,
&FxFxReader::setBeamA,
&FxFxReader::getBeamA, 0, 0, 0);
static Parameter<FxFxReader,long> interfaceBeamB
("BeamB",
"The PDG id of the incoming particle along the negative z-axis. "
"If zero the corresponding information is to be deduced from the "
"event stream/file.",
0, 0, 0, 0,
true, false, false,
&FxFxReader::setBeamB,
&FxFxReader::getBeamB, 0, 0, 0);
static Parameter<FxFxReader,Energy> interfaceEBeamA
("EBeamA",
"The energy of the incoming particle along the positive z-axis. "
"If zero the corresponding information is to be deduced from the "
"event stream/file.",
0, GeV, ZERO, ZERO, 1000000000.0*GeV,
true, false, true,
&FxFxReader::setEBeamA, &FxFxReader::getEBeamA, 0, 0, 0);
static Parameter<FxFxReader,Energy> interfaceEBeamB
("EBeamB",
"The energy of the incoming particle along the negative z-axis. "
"If zero the corresponding information is to be deduced from the "
"event stream/file.",
0, GeV, ZERO, ZERO, 1000000000.0*GeV,
true, false, true,
&FxFxReader::setEBeamB, &FxFxReader::getEBeamB, 0, 0, 0);
static Reference<FxFxReader,PDFBase> interfacePDFA
("PDFA",
"The PDF used for incoming particle along the positive z-axis. "
"If null the corresponding information is to be deduced from the "
"event stream/file.",
0, true, false, true, true, false,
&FxFxReader::setPDFA, &FxFxReader::getPDFA, 0);
static Reference<FxFxReader,PDFBase> interfacePDFB
("PDFB",
"The PDF used for incoming particle along the negative z-axis. "
"If null the corresponding information is to be deduced from the "
"event stream/file.",
0, true, false, true, true, false,
&FxFxReader::setPDFB, &FxFxReader::getPDFB, 0);
static Parameter<FxFxReader,long> interfaceMaxScan
("MaxScan",
"The maximum number of events to scan to obtain information about "
"processes and cross section in the intialization.",
&FxFxReader::theMaxScan, -1, 0, 0,
true, false, false);
static Parameter<FxFxReader,string> interfaceCacheFileName
("CacheFileName",
"Name of file used to cache the events form the reader in a fast-readable "
"form. If empty, no cache file will be generated.",
&FxFxReader::theCacheFileName, "",
true, false);
interfaceCacheFileName.fileType();
static Switch<FxFxReader,bool> interfaceCutEarly
("CutEarly",
"Determines whether to apply cuts to events before converting to "
"ThePEG format.",
&FxFxReader::doCutEarly, true, true, false);
static SwitchOption interfaceCutEarlyYes
(interfaceCutEarly,
"Yes",
"Event are cut before converted.",
true);
static SwitchOption interfaceCutEarlyNo
(interfaceCutEarly,
"No",
"Events are not cut before converted.",
false);
static Reference<FxFxReader,PartonExtractor> interfacePartonExtractor
("PartonExtractor",
"The PartonExtractor object used to construct remnants. If no object is "
"provided the FxFxEventHandler object must provide one instead.",
&FxFxReader::thePartonExtractor, true, false, true, true, false);
static Reference<FxFxReader,Cuts> interfaceCuts
("Cuts",
"The Cuts object to be used for this reader. Note that these "
"must not be looser cuts than those used in the actual generation. "
"If no object is provided the FxFxEventHandler object must "
"provide one instead.",
&FxFxReader::theCuts, true, false, true, true, false);
static RefVector<FxFxReader,ReweightBase> interfaceReweights
("Reweights",
"A list of ThePEG::ReweightBase objects to modify this the weight of "
"this reader.",
&FxFxReader::reweights, 0, false, false, true, false);
static RefVector<FxFxReader,ReweightBase> interfacePreweights
("Preweights",
"A list of ThePEG::ReweightBase objects to bias the phase space for this "
"reader without influencing the actual cross section.",
&FxFxReader::preweights, 0, false, false, true, false);
static Switch<FxFxReader,bool> interfaceReweightPDF
("ReweightPDF",
"If the PDFs used in the generation for this reader is different "
"from the ones assumed by the associated PartonExtractor object, "
"should the events be reweighted to fit the latter?",
&FxFxReader::reweightPDF, false, true, false);
static SwitchOption interfaceReweightPDFNo
(interfaceReweightPDF, "No", "The event weights are kept as they are.",
false);
static SwitchOption interfaceReweightPDFYes
(interfaceReweightPDF,
"Yes", "The events are reweighted.", true);
static Switch<FxFxReader,bool> interfaceInitPDFs
("InitPDFs",
"If no PDFs were specified in <interface>PDFA</interface> or "
"<interface>PDFB</interface>for this reader, try to extract the "
"information from the event file and assign the relevant PDFBase"
"objects when the reader is initialized.",
&FxFxReader::doInitPDFs, false, true, false);
static SwitchOption interfaceInitPDFsYes
(interfaceInitPDFs,
"Yes",
"Extract PDFs during initialization.",
true);
static SwitchOption interfaceInitPDFsNo
(interfaceInitPDFs,
"No",
"Do not extract PDFs during initialization.",
false);
static Parameter<FxFxReader,int> interfaceMaxMultCKKW
("MaxMultCKKW",
"If this reader is to be used (possibly together with others) for CKKW-"
"reweighting and veto, this should give the multiplicity of outgoing "
"particles in the highest multiplicity matrix element in the group. "
"If set to zero, no CKKW procedure should be applied.",
&FxFxReader::theMaxMultCKKW, 0, 0, 0,
true, false, Interface::lowerlim);
static Parameter<FxFxReader,int> interfaceMinMultCKKW
("MinMultCKKW",
"If this reader is to be used (possibly together with others) for CKKW-"
"reweighting and veto, this should give the multiplicity of outgoing "
"particles in the lowest multiplicity matrix element in the group. If "
"larger or equal to <interface>MaxMultCKKW</interface>, no CKKW "
"procedure should be applied.",
&FxFxReader::theMinMultCKKW, 0, 0, 0,
true, false, Interface::lowerlim);
static Switch<FxFxReader,unsigned int> interfaceMomentumTreatment
("MomentumTreatment",
"Treatment of the momenta supplied by the interface",
&FxFxReader::theMomentumTreatment, 0, false, false);
static SwitchOption interfaceMomentumTreatmentAccept
(interfaceMomentumTreatment,
"Accept",
"Just accept the momenta given",
0);
static SwitchOption interfaceMomentumTreatmentRescaleEnergy
(interfaceMomentumTreatment,
"RescaleEnergy",
"Rescale the energy supplied so it is consistent with the mass",
1);
static SwitchOption interfaceMomentumTreatmentRescaleMass
(interfaceMomentumTreatment,
"RescaleMass",
"Rescale the mass supplied so it is consistent with the"
" energy and momentum",
2);
static Switch<FxFxReader,bool> interfaceWeightWarnings
("WeightWarnings",
"Determines if warnings about possible weight incompatibilities should "
"be issued when this reader is initialized.",
&FxFxReader::useWeightWarnings, true, true, false);
static SwitchOption interfaceWeightWarningsWarnAboutWeights
(interfaceWeightWarnings,
"WarnAboutWeights",
"Warn about possible incompatibilities with the weight option in the "
"Les Houches common block and the requested weight treatment.",
true);
static SwitchOption interfaceWeightWarningsDontWarnAboutWeights
(interfaceWeightWarnings,
"DontWarnAboutWeights",
"Do not warn about possible incompatibilities with the weight option "
"in the Les Houches common block and the requested weight treatment.",
false);
static Switch<FxFxReader,bool> interfaceAllowedTopReOpen
("AllowedToReOpen",
"Can the file be reopened if more events are requested than the file contains?",
&FxFxReader::theReOpenAllowed, true, false, false);
static SwitchOption interfaceAllowedTopReOpenYes
(interfaceAllowedTopReOpen,
"Yes",
"Allowed to reopen the file",
true);
static SwitchOption interfaceAllowedTopReOpenNo
(interfaceAllowedTopReOpen,
"No",
"Not allowed to reopen the file",
false);
static Switch<FxFxReader,bool> interfaceIncludeSpin
("IncludeSpin",
"Use the spin information present in the event file, for tau leptons"
" only as this is the only case which makes any sense",
&FxFxReader::theIncludeSpin, true, false, false);
static SwitchOption interfaceIncludeSpinYes
(interfaceIncludeSpin,
"Yes",
"Use the spin information",
true);
static SwitchOption interfaceIncludeSpinNo
(interfaceIncludeSpin,
"No",
"Don't use the spin information",
false);
interfaceCuts.rank(8);
interfacePartonExtractor.rank(7);
interfaceBeamA.rank(5);
interfaceBeamB.rank(4);
interfaceEBeamA.rank(3);
interfaceEBeamB.rank(2);
interfaceMaxMultCKKW.rank(1.5);
interfaceMinMultCKKW.rank(1.0);
interfaceBeamA.setHasDefault(false);
interfaceBeamB.setHasDefault(false);
interfaceEBeamA.setHasDefault(false);
interfaceEBeamB.setHasDefault(false);
interfaceMaxMultCKKW.setHasDefault(false);
interfaceMinMultCKKW.setHasDefault(false);
}
namespace ThePEG {
ostream & operator<<(ostream & os, const HEPEUP & h) {
os << "<event>\n"
<< " " << setw(4) << h.NUP
<< " " << setw(6) << h.IDPRUP
<< " " << setw(14) << h.XWGTUP
<< " " << setw(14) << h.SCALUP
<< " " << setw(14) << h.AQEDUP
<< " " << setw(14) << h.AQCDUP << "\n";
for ( int i = 0; i < h.NUP; ++i )
os << " " << setw(8) << h.IDUP[i]
<< " " << setw(2) << h.ISTUP[i]
<< " " << setw(4) << h.MOTHUP[i].first
<< " " << setw(4) << h.MOTHUP[i].second
<< " " << setw(4) << h.ICOLUP[i].first
<< " " << setw(4) << h.ICOLUP[i].second
<< " " << setw(14) << h.PUP[i][0]
<< " " << setw(14) << h.PUP[i][1]
<< " " << setw(14) << h.PUP[i][2]
<< " " << setw(14) << h.PUP[i][3]
<< " " << setw(14) << h.PUP[i][4]
<< " " << setw(1) << h.VTIMUP[i]
<< " " << setw(1) << h.SPINUP[i] << std::endl;
os << "</event>" << std::endl;
return os;
}
}
diff --git a/MatrixElement/Gamma/MEGammaGamma2PiPi.cc b/MatrixElement/Gamma/MEGammaGamma2PiPi.cc
--- a/MatrixElement/Gamma/MEGammaGamma2PiPi.cc
+++ b/MatrixElement/Gamma/MEGammaGamma2PiPi.cc
@@ -1,182 +1,174 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MEGammaGamma2PiPi class.
//
#include "MEGammaGamma2PiPi.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "Herwig/MatrixElement/HardVertex.h"
using namespace Herwig;
using ThePEG::Helicity::incoming;
MEGammaGamma2PiPi::MEGammaGamma2PiPi() {
massOption(vector<unsigned int>(2,1));
}
void MEGammaGamma2PiPi::getDiagrams() const {
tcPDPtr gamma = getParticleData(ParticleID::gamma);
tcPDPtr pip = getParticleData(ParticleID::piplus);
tcPDPtr pim = pip->CC();
// first t-channel
add(new_ptr((Tree2toNDiagram(3),gamma,pip,gamma,1,pip, 2,pim,-1)));
// interchange
add(new_ptr((Tree2toNDiagram(3),gamma,pip,gamma,2,pip, 1,pim,-2)));
}
Energy2 MEGammaGamma2PiPi::scale() const {
return 2.*sHat()*tHat()*uHat()/(sqr(sHat())+sqr(tHat())+sqr(uHat()));
}
double MEGammaGamma2PiPi::me2() const {
VectorWaveFunction p1w(rescaledMomenta()[0],mePartonData()[0],incoming);
VectorWaveFunction p2w(rescaledMomenta()[1],mePartonData()[1],incoming);
vector<VectorWaveFunction> p1,p2;
for(unsigned int ix=0;ix<2;++ix) {
p1w.reset(2*ix);p1.push_back(p1w);
p2w.reset(2*ix);p2.push_back(p2w);
}
// calculate the matrix element
return helicityME(p1,p2,rescaledMomenta(),false);
}
unsigned int MEGammaGamma2PiPi::orderInAlphaS() const {
return 0;
}
unsigned int MEGammaGamma2PiPi::orderInAlphaEW() const {
return 2;
}
Selector<MEBase::DiagramIndex>
MEGammaGamma2PiPi::diagrams(const DiagramVector & diags) const {
Selector<DiagramIndex> sel;
for ( DiagramIndex i = 0; i < diags.size(); ++i )
if ( diags[i]->id() == -1 ) sel.insert(meInfo()[0], i);
else if ( diags[i]->id() == -2 ) sel.insert(meInfo()[1], i);
return sel;
}
Selector<const ColourLines *>
MEGammaGamma2PiPi::colourGeometries(tcDiagPtr ) const {
static ColourLines c1("");
Selector<const ColourLines *> sel;
sel.insert(1.0, &c1);
return sel;
}
IBPtr MEGammaGamma2PiPi::clone() const {
return new_ptr(*this);
}
IBPtr MEGammaGamma2PiPi::fullclone() const {
return new_ptr(*this);
}
-void MEGammaGamma2PiPi::persistentOutput(PersistentOStream & os) const {
-}
-
-void MEGammaGamma2PiPi::persistentInput(PersistentIStream & is, int) {
-}
-
// The following static variable is needed for the type
// description system in ThePEG.
-DescribeClass<MEGammaGamma2PiPi,HwMEBase>
+DescribeNoPIOClass<MEGammaGamma2PiPi,HwMEBase>
describeHerwigMEGammaGamma2PiPi("Herwig::MEGammaGamma2PiPi", "HwMEGammaGamma.so");
void MEGammaGamma2PiPi::Init() {
static ClassDocumentation<MEGammaGamma2PiPi> documentation
("The MEGammaGamma2PiPi class provides a simple matrix element for gamma gamma -> pi+pi-");
}
void MEGammaGamma2PiPi::constructVertex(tSubProPtr sub) {
// extract the particles in the hard process
ParticleVector hard;
hard.push_back(sub->incoming().first);
hard.push_back(sub->incoming().second);
hard.push_back(sub->outgoing()[0]);
hard.push_back(sub->outgoing()[1]);
// order of particles
unsigned int order[4]={0,1,2,3};
// identify the process and calculate matrix element
vector<VectorWaveFunction> p1,p2;
if(hard[order[2]]->id()<0) swap(order[2],order[3]);
VectorWaveFunction (p1 ,hard[order[0]],incoming,false,true);
VectorWaveFunction (p2 ,hard[order[1]],incoming,false,true);
p1[1]=p1[2];
p2[1]=p2[2];
vector<Lorentz5Momentum> momenta;
for(unsigned int ix=0;ix<4;++ix)
momenta.push_back(hard[order[ix]]->momentum());
helicityME(p1,p2,momenta,true);
// construct the vertex
HardVertexPtr hardvertex=new_ptr(HardVertex());
// set the matrix element for the vertex
hardvertex->ME(me_);
// set the pointers and to and from the vertex
for(unsigned int ix=0;ix<4;++ix) {
if(hard[order[ix]]->spinInfo())
hard[order[ix]]->spinInfo()->productionVertex(hardvertex);
}
}
double MEGammaGamma2PiPi::helicityME(vector<VectorWaveFunction> &p1,
vector<VectorWaveFunction> &p2,
const vector<Lorentz5Momentum> & momenta,
bool calc) const {
// for(unsigned int ix=0;ix<4;++ix)
// cerr << mePartonData()[ix]->PDGName() <<" " << meMomenta()[ix]/GeV << " " << meMomenta()[ix].mass()/GeV << "\n";
// double beta = meMomenta()[2].vect().mag()/meMomenta()[2].t();
// double ct = meMomenta()[2].cosTheta();
// double phi = meMomenta()[2].phi();
- // scale (external photons so scale in couplings is 0)
- Energy2 mt(0.*GeV2);
// matrix element to be stored
if(calc) me_.reset(ProductionMatrixElement(PDT::Spin1,PDT::Spin1,
PDT::Spin0,PDT::Spin0));
// calculate the matrix element
double output(0.),sumdiag[2]={0.,0.};
Complex diag[2];
Energy2 d1 = momenta[0]*momenta[2], d2 = momenta[1]*momenta[2];
for(unsigned int ihel1=0;ihel1<2;++ihel1) {
complex<Energy> a1 = momenta[2]*p1[ihel1].wave();
complex<Energy> a2 = momenta[3]*p1[ihel1].wave();
for(unsigned int ihel2=0;ihel2<2;++ihel2) {
complex<Energy> b1 = momenta[2]*p2[ihel2].wave();
complex<Energy> b2 = momenta[3]*p2[ihel2].wave();
// t-channel diagram
diag[0] = a1*b2/d1;
// u-channel diagram
diag[1] = a2*b1/d2;
sumdiag[0] += norm(diag[0]);
sumdiag[1] += norm(diag[1]);
Complex amp = p1[ihel1].wave()*p2[ihel2].wave()-diag[0]-diag[1];
output += norm(amp);
// store the me if needed
if(calc) me_(2*ihel1,2*ihel2,0,0) = amp;
}
}
// diagrams
DVector save;
save.push_back(sumdiag[0]);
save.push_back(sumdiag[1]);
meInfo(save);
// code to test vs the analytic result
// Energy2 m2 = sqr(momenta[2].mass());
// double test = 2. + ((d1 + d2)*m2*(-2*d1*d2 + (d1 + d2)*m2))/(sqr(d1)*sqr(d2));
// cerr << "testing ME " << (output-test)/(output+test) << " " << output << " " << test << " " << output/test << "\n";
// coupling factors
return output*sqr(SM().alphaEM()*4.*Constants::pi);
}
diff --git a/MatrixElement/Gamma/MEGammaGamma2PiPi.h b/MatrixElement/Gamma/MEGammaGamma2PiPi.h
--- a/MatrixElement/Gamma/MEGammaGamma2PiPi.h
+++ b/MatrixElement/Gamma/MEGammaGamma2PiPi.h
@@ -1,168 +1,152 @@
// -*- C++ -*-
#ifndef Herwig_MEGammaGamma2PiPi_H
#define Herwig_MEGammaGamma2PiPi_H
//
// This is the declaration of the MEGammaGamma2PiPi class.
//
#include "Herwig/MatrixElement/HwMEBase.h"
#include "Herwig/MatrixElement/ProductionMatrixElement.h"
#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
namespace Herwig {
using namespace ThePEG;
using ThePEG::Helicity::VectorWaveFunction;
/**
* The MEGammaGamma2PiPi class provides a smiple matrix element for \f$\gamma\gamma\to \pi^+\pi^-$ using scalar QED
*
* @see \ref MEGammaGamma2PiPiInterfaces "The interfaces"
* defined for MEGammaGamma2PiPi.
*/
class MEGammaGamma2PiPi: public HwMEBase {
public:
/**
* The default constructor.
*/
MEGammaGamma2PiPi();
public:
/** @name Virtual functions required by the MEBase class. */
//@{
/**
* Return the order in \f$\alpha_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInAlphaS() const;
/**
* Return the order in \f$\alpha_{EW}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInAlphaEW() const;
/**
* The matrix element for the kinematical configuration
* previously provided by the last call to setKinematics(), suitably
* scaled by sHat() to give a dimension-less number.
* @return the matrix element scaled with sHat() to give a
* dimensionless number.
*/
virtual double me2() const;
/**
* Return the scale associated with the last set phase space point.
*/
virtual Energy2 scale() const;
/**
* Add all possible diagrams with the add() function.
*/
virtual void getDiagrams() const;
/**
* Get diagram selector. With the information previously supplied with the
* setKinematics method, a derived class may optionally
* override this method to weight the given diagrams with their
* (although certainly not physical) relative probabilities.
* @param dv the diagrams to be weighted.
* @return a Selector relating the given diagrams to their weights.
*/
virtual Selector<DiagramIndex> diagrams(const DiagramVector & dv) const;
/**
* Return a Selector with possible colour geometries for the selected
* diagram weighted by their relative probabilities.
* @param diag the diagram chosen.
* @return the possible colour geometries weighted by their
* relative probabilities.
*/
virtual Selector<const ColourLines *>
colourGeometries(tcDiagPtr diag) const;
//@}
/**
* Construct the vertex of spin correlations.
*/
virtual void constructVertex(tSubProPtr);
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:
/**
* Matrix element for \f$\gamma\gamma\to q\bar{q}\f$
* @param p1 The wavefunctions for the first incoming photon
* @param p2 The wavefunctions for the second incoming photon
* @param momenta The momenta
* @param calc Whether or not to calculate the matrix element
*/
double helicityME(vector<VectorWaveFunction> &p1,vector<VectorWaveFunction> &p2,
const vector<Lorentz5Momentum> & momenta,
bool calc) const;
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MEGammaGamma2PiPi & operator=(const MEGammaGamma2PiPi &) = delete;
private:
/**
* Matrix element
*/
mutable ProductionMatrixElement me_;
};
}
#endif /* Herwig_MEGammaGamma2PiPi_H */
diff --git a/MatrixElement/MEMultiChannel.cc b/MatrixElement/MEMultiChannel.cc
--- a/MatrixElement/MEMultiChannel.cc
+++ b/MatrixElement/MEMultiChannel.cc
@@ -1,146 +1,146 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MEMultiChannel class.
//
#include "MEMultiChannel.h"
#include "Herwig/Decay/DecayIntegrator.fh"
#include "Herwig/Decay/PhaseSpaceMode.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/Cuts/Cuts.h"
using namespace Herwig;
MEMultiChannel::~MEMultiChannel() {}
void MEMultiChannel::getDiagrams() const {
int ndiag=0;
channelMap_.clear();
for(PhaseSpaceModePtr mode : modes_) {
channelMap_.push_back(map<int,int>());
for(unsigned int ix=0;ix<mode->channels().size();++ix) {
ThePEG::Ptr<ThePEG::Tree2toNDiagram>::pointer diag = mode->channels()[ix].createDiagram();
ndiag+=1;
diag = new_ptr((*diag,-ndiag));
channelMap_.back()[ndiag]= ix;
add(diag);
}
}
}
Energy2 MEMultiChannel::scale() const {
return sHat();
}
int MEMultiChannel::nDim() const {
return 0;
// return modes_[0]->nRand();
}
-bool MEMultiChannel::generateKinematics(const double * r) {
+bool MEMultiChannel::generateKinematics(const double * ) {
// first find the mode
int imode = -1;
for(unsigned int ix=0;ix<modes_.size();++ix) {
bool matched=true;
for(unsigned int iy=0;iy<modes_[ix]->outgoing().size();++iy) {
if(mePartonData()[iy+2]!=modes_[ix]->outgoing()[iy]) {
matched=false;
break;
}
}
if(matched) {
imode=ix;
break;
}
}
assert(imode>=0);
// fill the stack of random numbers
modes_[imode]->fillStack();
//modes_[imode]->fillStack(r);
// generate the momenta
int ichan;
vector<Lorentz5Momentum> momenta(meMomenta().size()-2);
Lorentz5Momentum pcm=meMomenta()[0]+meMomenta()[1];
Energy wgt = modes_[imode]->weight(ichan,pcm,momenta);
// set the jacobian
jacobian(wgt/sqrt(sHat()));
// and momenta
for(unsigned int ix=0;ix<momenta.size();++ix)
meMomenta()[ix+2]=momenta[ix];
// check the cuts
tcPDVector tout(momenta.size());
vector<LorentzMomentum> out(meMomenta().size()-2);
for(unsigned int ix=2;ix<meMomenta().size();++ix) {
tout[ix-2] = mePartonData()[ix];
out[ix-2]=meMomenta()[ix];
}
if ( !lastCuts().passCuts(tout, out, mePartonData()[0], mePartonData()[1]) )
return false;
// passed cuts
return true;
}
CrossSection MEMultiChannel::dSigHatDR() const {
return sqr(hbarc)*me2()*jacobian()/sHat();
}
Selector<MEBase::DiagramIndex>
MEMultiChannel::diagrams(const DiagramVector & diags) const {
Selector<DiagramIndex> sel;
for ( DiagramIndex i = 0; i < diags.size(); ++i ) {
double wgt = me2(channelMap_[iMode_][-diags[i]->id()] );
sel.insert(wgt, i);
}
return sel;
}
Selector<const ColourLines *>
MEMultiChannel::colourGeometries(tcDiagPtr ) const {
static ColourLines none("");
Selector<const ColourLines *> sel;
sel.insert(1.0, &none);
return sel;
}
void MEMultiChannel::persistentOutput(PersistentOStream & os) const {
os << modes_ << channelMap_;
}
void MEMultiChannel::persistentInput(PersistentIStream & is, int) {
is >> modes_ >> channelMap_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeAbstractClass<MEMultiChannel,MEBase>
describeHerwigMEMultiChannel("Herwig::MEMultiChannel", "Herwig.so");
void MEMultiChannel::Init() {
static ClassDocumentation<MEMultiChannel> documentation
("There is no documentation for the MEMultiChannel class");
}
void MEMultiChannel::doinit() {
MEBase::doinit();
for(tPhaseSpaceModePtr mode : modes_)
mode->init();
}
void MEMultiChannel::doinitrun() {
MEBase::doinitrun();
for(tPhaseSpaceModePtr mode : modes_)
mode->initrun();
}
diff --git a/MatrixElement/Makefile.am b/MatrixElement/Makefile.am
--- a/MatrixElement/Makefile.am
+++ b/MatrixElement/Makefile.am
@@ -1,18 +1,18 @@
-SUBDIRS = General Lepton Hadron DIS Powheg Gamma Matchbox Reweighters EW
+SUBDIRS = General Lepton Hadron DIS Powheg Gamma Matchbox Reweighters
if WANT_LIBFASTJET
SUBDIRS += FxFx
endif
noinst_LTLIBRARIES = libHwME.la
libHwME_la_SOURCES = \
HwMEBase.h HwMEBase.fh HwMEBase.cc \
MEMultiChannel.h MEMultiChannel.cc \
MEfftoVH.h MEfftoVH.cc \
MEfftoffH.h MEfftoffH.cc \
HardVertex.fh HardVertex.h HardVertex.cc \
ProductionMatrixElement.h ProductionMatrixElement.cc \
DrellYanBase.h DrellYanBase.cc \
BlobME.h BlobME.cc \
MEMinBias.h MEMinBias.cc
diff --git a/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc b/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc
--- a/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc
+++ b/MatrixElement/Matchbox/Base/MatchboxAmplitude.cc
@@ -1,959 +1,957 @@
// -*- C++ -*-
//
// MatchboxAmplitude.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MatchboxAmplitude class.
//
#include "MatchboxAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinorHelicity.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SU2Helper.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
#include "ThePEG/Utilities/StringUtils.h"
#include "MatchboxMEBase.h"
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <iterator>
using std::ostream_iterator;
using namespace Herwig;
MatchboxAmplitude::MatchboxAmplitude()
: Amplitude(), theCleanupAfter(20),
treeLevelHelicityPoints(0),
oneLoopHelicityPoints(0),
theTrivialColourLegs(false) {
}
-MatchboxAmplitude::~MatchboxAmplitude() {}
-
void MatchboxAmplitude::persistentOutput(PersistentOStream & os) const {
os << theLastXComb << theColourBasis
<< theCleanupAfter << treeLevelHelicityPoints << oneLoopHelicityPoints
<< theTrivialColourLegs << theReshuffleMasses.size();
if ( !theReshuffleMasses.empty() ) {
for (auto const & r : theReshuffleMasses )
os << r.first << ounit(r.second,GeV);
}
}
void MatchboxAmplitude::persistentInput(PersistentIStream & is, int) {
size_t reshuffleSize;
is >> theLastXComb >> theColourBasis
>> theCleanupAfter >> treeLevelHelicityPoints >> oneLoopHelicityPoints
>> theTrivialColourLegs >> reshuffleSize;
theReshuffleMasses.clear();
while ( reshuffleSize > 0 ) {
long id; Energy m;
is >> id >> iunit(m,GeV);
theReshuffleMasses[id] = m;
--reshuffleSize;
}
lastMatchboxXComb(theLastXComb);
}
Ptr<MatchboxFactory>::tptr MatchboxAmplitude::factory() const {
return MatchboxFactory::currentFactory();
}
void MatchboxAmplitude::doinit() {
Amplitude::doinit();
if ( colourBasis() ) {
colourBasis()->init();
}
}
void MatchboxAmplitude::doinitrun() {
Amplitude::doinitrun();
if ( colourBasis())
colourBasis()->initrun();
}
void MatchboxAmplitude::cloneDependencies(const std::string&,bool) {}
MatchboxMEBasePtr MatchboxAmplitude::makeME(const PDVector&) const {
return new_ptr(MatchboxMEBase());
}
Selector<const ColourLines *> MatchboxAmplitude::colourGeometries(tcDiagPtr d) const {
if ( haveColourFlows() )
return colourBasis()->colourGeometries(d,lastLargeNAmplitudes());
return Selector<const ColourLines *>();
}
void MatchboxAmplitude::olpOrderFileHeader(ostream& os) const {
os << "# OLP order file created by Herwig/Matchbox\n\n";
os << "InterfaceVersion BLHA2\n\n";
os << "Model SM\n"
<< "CorrectionType QCD\n"
<< "IRregularisation " << (isDR() ? "DRED" : "CDR") << "\n"
<< "Extra HelAvgInitial no\n"
<< "Extra ColAvgInitial no\n"
<< "Extra MCSymmetrizeFinal no\n";
os << "\n";
}
void MatchboxAmplitude::olpOrderFileProcesses(ostream& os,
const map<pair<Process,int>,int>& proc) const {
map<int,pair<Process,int> > sorted;
for (auto const & p : proc ) {
sorted[p.second] = p.first;
}
unsigned int currentOrderInAlphaS = sorted.begin()->second.first.orderInAlphaS;
unsigned int currentOrderInAlphaEW = sorted.begin()->second.first.orderInAlphaEW;
int currentType = sorted.begin()->second.second;
os << "AlphasPower " << currentOrderInAlphaS << "\n"
<< "AlphaPower " << currentOrderInAlphaEW << "\n"
<< "AmplitudeType ";
if ( currentType == ProcessType::treeME2 ) {
os << "tree\n";
} else if ( currentType == ProcessType::oneLoopInterference ) {
os << "loop\n";
} else if ( currentType == ProcessType::colourCorrelatedME2 ) {
os << "cctree\n";
} else if ( currentType == ProcessType::spinColourCorrelatedME2 ) {
os << "sctree\n";
} else if ( currentType == ProcessType::loopInducedME2 ) {
os << "loopinduced\n";
} else if ( currentType == ProcessType::spinCorrelatedME2 ) {
os << "stree\n";
} else assert(false);
for ( map<int,pair<Process,int> >::const_iterator p = sorted.begin();
p != sorted.end(); ++p ) {
if ( currentOrderInAlphaS != p->second.first.orderInAlphaS ) {
currentOrderInAlphaS = p->second.first.orderInAlphaS;
os << "AlphasPower " << currentOrderInAlphaS << "\n";
}
if ( currentOrderInAlphaEW != p->second.first.orderInAlphaEW ) {
currentOrderInAlphaEW = p->second.first.orderInAlphaEW;
os << "AlphaPower " << currentOrderInAlphaEW << "\n";
}
if ( currentType != p->second.second ) {
currentType = p->second.second;
os << "AmplitudeType ";
if ( currentType == ProcessType::treeME2 ) {
os << "tree\n";
} else if ( currentType == ProcessType::oneLoopInterference ) {
os << "loop\n";
} else if ( currentType == ProcessType::colourCorrelatedME2 ) {
os << "cctree\n";
} else if ( currentType == ProcessType::spinColourCorrelatedME2 ) {
os << "sctree\n";
} else if ( currentType == ProcessType::spinCorrelatedME2 ) {
os << "stree\n";
} else assert(false);
}
os << p->second.first.legs[0]->id() << " "
<< p->second.first.legs[1]->id() << " -> ";
for ( PDVector::const_iterator o = p->second.first.legs.begin() + 2;
o != p->second.first.legs.end(); ++o ) {
os << (**o).id() << " ";
}
os << "\n";
}
}
bool MatchboxAmplitude::startOLP(const map<pair<Process,int>,int>& procs) {
string orderFileName = factory()->buildStorage() + name() + ".OLPOrder.lh";
ofstream orderFile(orderFileName.c_str());
olpOrderFileHeader(orderFile);
olpOrderFileProcesses(orderFile,procs);
string contractFileName = factory()->buildStorage() + name() + ".OLPContract.lh";
signOLP(orderFileName, contractFileName);
// TODO check the contract file
int status = 0;
startOLP(contractFileName, status);
if ( status != 1 )
return false;
return true;
}
struct orderPartonData {
bool operator()(const pair<tcPDPtr,int>& a,
const pair<tcPDPtr,int>& b) const {
if ( a.first == b.first )
return a.second < b.second;
int acolour = a.first->iColour();
int bcolour = b.first->iColour();
if ( abs(acolour) != abs(bcolour) )
return abs(acolour) < abs(bcolour);
if ( a.first->iSpin() != b.first->iSpin() )
return a.first->iSpin() < b.first->iSpin();
int acharge = a.first->iCharge();
int bcharge = b.first->iCharge();
if ( abs(acharge) != abs(bcharge) )
return abs(acharge) < abs(bcharge);
if ( abs(a.first->id()) != abs(b.first->id()) )
return abs(a.first->id()) < abs(b.first->id());
return a.first->id() > b.first->id();
}
};
void MatchboxAmplitude::setXComb(tStdXCombPtr xc) {
theLastXComb = xc;
lastMatchboxXComb(xc);
fillCrossingMap();
if ( ( treeAmplitudes() || oneLoopAmplitudes() ) &&
hasAmplitudeMomenta() )
for ( size_t k = 0 ; k < meMomenta().size(); ++k )
amplitudeMomenta()[k] = amplitudeMomentum(k);
}
void MatchboxAmplitude::fillCrossingMap(size_t shift) {
if ( !amplitudePartonData().empty() )
return;
double csign = 1.;
set<pair<tcPDPtr,int>,orderPartonData > processLegs;
for ( unsigned int l = 0; l < mePartonData().size(); ++l ) {
if ( l > 1 )
processLegs.insert(make_pair(mePartonData()[l],l));
else {
if ( mePartonData()[l]->CC() ) {
processLegs.insert(make_pair(mePartonData()[l]->CC(),l));
if ( mePartonData()[l]->iSpin() == PDT::Spin1Half )
csign *= -1.;
} else {
processLegs.insert(make_pair(mePartonData()[l],l));
}
}
}
crossingSign(csign);
set<pair<tcPDPtr,int> > amplitudeLegs;
crossingMap().resize(mePartonData().size());
amplitudePartonData().resize(mePartonData().size());
if ( hasAmplitudeMomenta() )
amplitudeMomenta().resize(mePartonData().size());
int ampCount = 0;
// process legs are already sorted, we only need to arrange for
// adjacent particles and anti-particles
while ( !processLegs.empty() ) {
set<pair<tcPDPtr,int>,orderPartonData >::iterator next
= processLegs.begin();
while ( next->first->id() < 0 ) {
if ( ++next == processLegs.end() )
break;
}
//This happens for e.g. p p-> W- gamma & p p->W- W- j j
//Still working for pp->W-H-W- e+ nue jj ???
if(next == processLegs.end()){
next = processLegs.begin();
for (;next!=processLegs.end();next++){
assert(next->first->id() < 0 );
crossingMap()[ampCount] = next->second - shift;
amplitudeLegs.insert(make_pair(next->first,ampCount));
++ampCount;
processLegs.erase(next);
}
break;
}
crossingMap()[ampCount] = next->second - shift;
amplitudeLegs.insert(make_pair(next->first,ampCount));
tcPDPtr check = next->first;
processLegs.erase(next);
++ampCount;
if ( check->CC() ) {
set<pair<tcPDPtr,int>,orderPartonData>::iterator checkcc
= processLegs.end();
for ( set<pair<tcPDPtr,int>,orderPartonData>::iterator c = processLegs.begin();
c != processLegs.end(); ++c ) {
if ( c->first == check->CC() ) {
checkcc = c; break;
}
}
if ( checkcc == processLegs.end() )
for ( set<pair<tcPDPtr,int>,orderPartonData>::iterator c = processLegs.begin();
c != processLegs.end(); ++c ) {
if ( !SU2Helper::SU2CC(check) )
continue;
if ( c->first == SU2Helper::SU2CC(check)->CC() ) {
checkcc = c; break;
}
}
if ( checkcc == processLegs.end() ) {
int f = SU2Helper::family(check);
for ( int i = 1 - f; i < 5 - f; i++ ) {
bool gotone = false;
for ( set<pair<tcPDPtr,int>,orderPartonData>::iterator c = processLegs.begin();
c != processLegs.end(); ++c ) {
if ( !SU2Helper::SU2CC(check,i) )
continue;
if ( c->first == SU2Helper::SU2CC(check,i)->CC() ) {
checkcc = c; gotone = true; break;
}
}
if ( gotone )
break;
}
}
// default to just pick the next available anti-particle
if ( processLegs.empty() ) break;
if ( checkcc == processLegs.end() ) {
checkcc = processLegs.begin();
while ( checkcc->first->id() > 0 )
if ( ++checkcc == processLegs.end() )
break;
}
// if still not there, use whatever is available at the end
if ( checkcc == processLegs.end() )
checkcc = processLegs.begin();
crossingMap()[ampCount] = checkcc->second - shift;
amplitudeLegs.insert(make_pair(checkcc->first,ampCount));
processLegs.erase(checkcc);
++ampCount;
}
}
for ( set<pair<tcPDPtr,int> >::const_iterator l = amplitudeLegs.begin();
l != amplitudeLegs.end(); ++l )
amplitudePartonData()[l->second] = l->first;
if ( colourBasis() && !colourBasis()->indexMap().empty()) {
assert(colourBasis()->indexMap().find(mePartonData()) !=
colourBasis()->indexMap().end());
const map<size_t,size_t> colourCross =
colourBasis()->indexMap().find(mePartonData())->second;
for ( size_t k = 0; k < crossingMap().size(); ++k ) {
if ( colourCross.find(crossingMap()[k]) !=
colourCross.end() ) {
size_t ccross = colourCross.find(crossingMap()[k])->second;
amplitudeToColourMap()[k] = ccross;
colourToAmplitudeMap()[ccross] = k;
}
}
}
}
const string& MatchboxAmplitude::colourOrderingString(size_t id) const {
static string empty = "";
if ( !colourBasis() ) {
return empty;
}
return colourBasis()->orderingString(mePartonData(),colourToAmplitudeMap(),id);
}
const set<vector<size_t> >& MatchboxAmplitude::colourOrdering(size_t id) const {
static set<vector<size_t> > empty;
if ( !colourBasis() ) {
return empty;
}
return colourBasis()->ordering(mePartonData(),colourToAmplitudeMap(),id);
}
Lorentz5Momentum MatchboxAmplitude::amplitudeMomentum(int i) const {
int iCrossed = crossingMap()[i];
Lorentz5Momentum res = meMomenta()[iCrossed];
if ( iCrossed < 2 )
res = -res;
res.setMass(meMomenta()[iCrossed].mass());
Energy2 rho = res.t()*res.t() - res.mass2();
res.setRho(sqrt(abs(rho)));
return res;
}
set<vector<int> > MatchboxAmplitude::generateHelicities() const {
set<vector<int> > res;
vector<int> current(amplitudePartonData().size());
doGenerateHelicities(res,current,0);
return res;
}
void MatchboxAmplitude::doGenerateHelicities(set<vector<int> >& res,
vector<int>& current,
size_t pos) const {
if ( pos == amplitudePartonData().size() ) {
res.insert(current);
return;
}
if ( amplitudePartonData()[pos]->iSpin() == PDT::Spin0 ) {
current[pos] = 0;
doGenerateHelicities(res,current,pos+1);
} else if ( amplitudePartonData()[pos]->iSpin() == PDT::Spin1Half ) {
current[pos] = 1;
doGenerateHelicities(res,current,pos+1);
current[pos] = -1;
doGenerateHelicities(res,current,pos+1);
}else if (amplitudePartonData()[pos]->iSpin() == PDT::Spin1 ) {
if (amplitudePartonData()[pos]->hardProcessMass() != ZERO){
current[pos] = 0;
doGenerateHelicities(res,current,pos+1);
}
current[pos] = 1;
doGenerateHelicities(res,current,pos+1);
current[pos] = -1;
doGenerateHelicities(res,current,pos+1);
}
}
vector<unsigned int> MatchboxAmplitude::physicalHelicities(const vector<int>&) const {
throw Exception()
<< "MatchboxAmplitude::physicalHelicities(): The amplitude '" << name() << "' does not support the spin correlation algorithm"
<< Exception::runerror;
static vector<unsigned int> dummy;
return dummy;
}
void MatchboxAmplitude::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr) {
if ( !calculateTreeAmplitudes() )
return;
bool initialized =
!lastAmplitudes().empty() && treeLevelHelicityPoints > theCleanupAfter;
if ( !initialized ) {
treeLevelHelicityPoints++;
map<vector<int>,CVector> all;
map<vector<int>,CVector> allLargeN;
set<vector<int> > helicities = generateHelicities();
for ( set<vector<int> >::const_iterator h = helicities.begin();
h != helicities.end(); ++h ) {
all.insert(make_pair(*h,CVector(max(colourBasisDim(),1))));
allLargeN.insert(make_pair(*h,CVector(max(colourBasisDim(),1))));
}
AmplitudeIterator amp = all.begin();
AmplitudeIterator lamp = allLargeN.begin();
for ( ; amp != all.end(); ++amp, ++lamp ) {
for ( size_t k = 0; k < max(colourBasisDim(),1); ++k ){
amp->second(k) = evaluate(k,amp->first,lamp->second(k));
if ( amp->second(k) != Complex(0.0) ) {
if ( lastAmplitudes().find(amp->first)!=lastAmplitudes().end() ) {
lastAmplitudes().find(amp->first)->second = amp->second;
lastLargeNAmplitudes().find(lamp->first)->second = lamp->second;
} else {
lastAmplitudes().insert(*amp);
lastLargeNAmplitudes().insert(*lamp);
}
} else if ( lastAmplitudes().find(amp->first)!=lastAmplitudes().end() ){
lastAmplitudes().find(amp->first)->second = amp->second;
lastLargeNAmplitudes().find(lamp->first)->second = lamp->second;
}
}
}
} else {
AmplitudeIterator amp = lastAmplitudes().begin();
AmplitudeIterator lamp = lastLargeNAmplitudes().begin();
for ( ;amp != lastAmplitudes().end(); ++amp, ++lamp ) {
for ( size_t k = 0; k < max(colourBasisDim(),1); ++k ){
amp->second(k) = evaluate(k,amp->first,lamp->second(k));
}
}
}
haveTreeAmplitudes();
}
void MatchboxAmplitude::prepareOneLoopAmplitudes(Ptr<MatchboxMEBase>::tcptr) {
if ( !calculateOneLoopAmplitudes() )
return;
bool initialized =
!lastOneLoopAmplitudes().empty() && oneLoopHelicityPoints > theCleanupAfter;
if ( !initialized ) {
oneLoopHelicityPoints++;
map<vector<int>,CVector> all;
set<vector<int> > helicities = generateHelicities();
for ( set<vector<int> >::const_iterator h = helicities.begin();
h != helicities.end(); ++h ) {
all.insert(make_pair(*h,CVector(max(colourBasisDim(),1))));
}
AmplitudeIterator amp = all.begin();
for ( ; amp != all.end(); ++amp ) {
for ( size_t k = 0; k < max(colourBasisDim(),1); ++k ){
amp->second(k) = evaluateOneLoop(k,amp->first);
if ( amp->second(k) != Complex(0.0) ) {
if ( lastOneLoopAmplitudes().find(amp->first)!=lastOneLoopAmplitudes().end() ) {
lastOneLoopAmplitudes().find(amp->first)->second = amp->second;
} else{
lastOneLoopAmplitudes().insert(*amp);
}
} else if ( lastOneLoopAmplitudes().find(amp->first)!=lastOneLoopAmplitudes().end() ){
lastOneLoopAmplitudes().find(amp->first)->second = amp->second;
}
}
}
} else {
AmplitudeIterator amp = lastOneLoopAmplitudes().begin();
for ( ;amp != lastOneLoopAmplitudes().end(); ++amp ) {
for ( size_t k = 0; k < max(colourBasisDim(),1); ++k ){
amp->second(k) = evaluateOneLoop(k,amp->first);
}
}
}
haveOneLoopAmplitudes();
}
Complex MatchboxAmplitude::value(const tcPDVector&,
const vector<Lorentz5Momentum>&,
const vector<int>&) {
assert(false && "ThePEG::Amplitude interface is not sufficient at the moment.");
throw Exception() << "MatchboxAmplitude::value(): ThePEG::Amplitude interface is not sufficient at the moment."
<< Exception::runerror;
return 0.;
}
double MatchboxAmplitude::me2() const {
if ( !calculateTreeME2() )
return lastTreeME2();
lastTreeME2(colourBasis()->me2(mePartonData(),lastAmplitudes()));
return lastTreeME2();
}
double MatchboxAmplitude::largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const {
if ( !calculateLargeNME2() )
return lastLargeNME2();
double res = 0.;
if ( !trivialColourLegs() )
res = largeNBasis->me2(mePartonData(),lastLargeNAmplitudes());
else
res = me2();
lastLargeNME2(res);
return res;
}
double MatchboxAmplitude::oneLoopInterference() const {
if ( !calculateOneLoopInterference() )
return lastOneLoopInterference();
lastOneLoopInterference(colourBasis()->interference(mePartonData(),
lastOneLoopAmplitudes(),lastAmplitudes()));
return lastOneLoopInterference();
}
double MatchboxAmplitude::colourCharge(tcPDPtr data) const {
double cfac = 1.;
double Nc = generator()->standardModel()->Nc();
if ( data->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( data->iColour() == PDT::Colour3 ||
data->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
return cfac;
}
double MatchboxAmplitude::largeNColourCharge(tcPDPtr data) const {
double cfac = 1.;
double Nc = generator()->standardModel()->Nc();
if ( data->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( data->iColour() == PDT::Colour3 ||
data->iColour() == PDT::Colour3bar ) {
cfac = 0.5*Nc;
} else assert(false);
return cfac;
}
double MatchboxAmplitude::colourCorrelatedME2(pair<int,int> ij) const {
double cfac = colourCharge(mePartonData()[ij.first]);
if ( !calculateColourCorrelator(ij) )
return lastColourCorrelator(ij)/cfac;
double res = 0.;
if ( !trivialColourLegs() )
res = colourBasis()->colourCorrelatedME2(ij,mePartonData(),lastAmplitudes());
else {
// two partons TiTj = (-Ti^2-Tj^2)/2
// three partons TiTj = (-Ti^2-Tj^2+Tk^2)/2
int n = mePartonData().size();
for ( int i = 0; i < n; ++i ) {
if ( !mePartonData()[i]->coloured() )
continue;
if ( i == ij.first || i == ij.second )
res -= colourCharge(mePartonData()[i])*me2();
else
res += colourCharge(mePartonData()[i])*me2();
}
res *= 0.5;
}
lastColourCorrelator(ij,res);
return res/cfac;
}
double MatchboxAmplitude::largeNColourCorrelatedME2(pair<int,int> ij,
Ptr<ColourBasis>::tptr largeNBasis) const {
double cfac = largeNColourCharge(mePartonData()[ij.first]);
if ( !calculateLargeNColourCorrelator(ij) )
return lastLargeNColourCorrelator(ij)/cfac;
double res = 0.;
if ( !trivialColourLegs() )
res = largeNBasis->colourCorrelatedME2(ij,mePartonData(),lastLargeNAmplitudes());
else {
// two partons TiTj = (-Ti^2-Tj^2)/2
// three partons TiTj = (-Ti^2-Tj^2+Tk^2)/2
int n = mePartonData().size();
for ( int i = 0; i < n; ++i ) {
if ( !mePartonData()[i]->coloured() )
continue;
if ( i == ij.first || i == ij.second )
res -= largeNColourCharge(mePartonData()[i])*largeNME2(largeNBasis);
else
res += largeNColourCharge(mePartonData()[i])*largeNME2(largeNBasis);
}
res *= 0.5;
}
lastLargeNColourCorrelator(ij,res);
return res/cfac;
}
// compare int vectors modulo certain element
// which needs to differe between the two
bool equalsModulo(unsigned int i, const vector<int>& a, const vector<int>& b) {
assert(a.size()==b.size());
if ( a[i] == b[i] )
return false;
for ( unsigned int k = 0; k < a.size(); ++k ) {
if ( k == i )
continue;
if ( a[k] != b[k] )
return false;
}
return true;
}
LorentzVector<Complex> MatchboxAmplitude::plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n,
int) const {
using namespace SpinorHelicity;
LorentzVector<complex<Energy> > num =
PlusSpinorCurrent(PlusConjugateSpinor(n),MinusSpinor(p)).eval();
complex<Energy> den =
sqrt(2.)*PlusSpinorProduct(PlusConjugateSpinor(n),PlusSpinor(p)).eval();
LorentzVector<Complex> polarization(num.x()/den,num.y()/den,num.z()/den,num.t()/den);
return polarization;
}
double MatchboxAmplitude::spinColourCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
Lorentz5Momentum p = meMomenta()[ij.first];
Lorentz5Momentum n = meMomenta()[ij.second];
LorentzVector<Complex> polarization = plusPolarization(p,n,ij.first);
Complex pFactor = (polarization*c.momentum())/sqrt(abs(c.scale()));
double avg =
colourCorrelatedME2(ij)*(-c.diagonal()+ (c.scale() > ZERO ? 1. : -1.)*norm(pFactor));
int iCrossed = -1;
for ( unsigned int k = 0; k < crossingMap().size(); ++k )
if ( crossingMap()[k] == ij.first ) {
iCrossed = k;
break;
}
assert(iCrossed >= 0);
Complex csCorr = 0.0;
if ( calculateColourSpinCorrelator(ij) ) {
set<const CVector*> done;
for ( AmplitudeConstIterator a = lastAmplitudes().begin();
a != lastAmplitudes().end(); ++a ) {
if ( done.find(&(a->second)) != done.end() )
continue;
AmplitudeConstIterator b = lastAmplitudes().begin();
while ( !equalsModulo(iCrossed,a->first,b->first) )
if ( ++b == lastAmplitudes().end() )
break;
if ( b == lastAmplitudes().end() || done.find(&(b->second)) != done.end() )
continue;
done.insert(&(a->second)); done.insert(&(b->second));
if ( a->first[iCrossed] == 1 )
swap(a,b);
csCorr += colourBasis()->colourCorrelatedInterference(ij,mePartonData(),a->second,b->second);
}
lastColourSpinCorrelator(ij,csCorr);
} else {
csCorr = lastColourSpinCorrelator(ij);
}
double corr =
2.*real(csCorr*sqr(pFactor));
double Nc = generator()->standardModel()->Nc();
double cfac = 1.;
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
return
avg + (c.scale() > ZERO ? 1. : -1.)*corr/cfac;
}
double MatchboxAmplitude::spinCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
Lorentz5Momentum p = meMomenta()[ij.first];
Lorentz5Momentum n = meMomenta()[ij.second];
LorentzVector<Complex> polarization = plusPolarization(p,n,ij.first);
Complex pFactor = (polarization*c.momentum())/sqrt(abs(c.scale()));
double avg =
me2()*(-c.diagonal()+ (c.scale() > ZERO ? 1. : -1.)*norm(pFactor));
int iCrossed = -1;
for ( unsigned int k = 0; k < crossingMap().size(); ++k )
if ( crossingMap()[k] == ij.first ) {
iCrossed = k;
break;
}
assert(iCrossed >= 0);
Complex csCorr = 0.0;
if ( calculateSpinCorrelator(ij) ) {
set<const CVector*> done;
for ( AmplitudeConstIterator a = lastAmplitudes().begin();
a != lastAmplitudes().end(); ++a ) {
if ( done.find(&(a->second)) != done.end() )
continue;
AmplitudeConstIterator b = lastAmplitudes().begin();
while ( !equalsModulo(iCrossed,a->first,b->first) )
if ( ++b == lastAmplitudes().end() )
break;
if ( b == lastAmplitudes().end() || done.find(&(b->second)) != done.end() )
continue;
done.insert(&(a->second)); done.insert(&(b->second));
if ( a->first[iCrossed] == 1 )
swap(a,b);
csCorr += colourBasis()->interference(mePartonData(),a->second,b->second);
}
lastSpinCorrelator(ij,csCorr);
} else {
csCorr = lastSpinCorrelator(ij);
}
double corr =
2.*real(csCorr*sqr(pFactor));
return
avg + (c.scale() > ZERO ? 1. : -1.)*corr;
}
void MatchboxAmplitude::checkReshuffling(Ptr<MatchboxPhasespace>::tptr ps) {
set<long> noReshuffle;
for ( map<long,Energy>::const_iterator m = reshuffleMasses().begin();
m != reshuffleMasses().end(); ++m ) {
tcPDPtr data = getParticleData(m->first);
assert(data);
bool needReshuffle = m->second != data->hardProcessMass();
needReshuffle |=
(data->hardProcessWidth() != ZERO || data->massGenerator()) &&
ps->useMassGenerators();
if ( !needReshuffle )
noReshuffle.insert(m->first);
}
for ( set<long>::const_iterator rm = noReshuffle.begin();
rm != noReshuffle.end(); ++rm )
theReshuffleMasses.erase(*rm);
}
string MatchboxAmplitude::doReshuffle(string in) {
in = StringUtils::stripws(in);
if ( in.empty() )
throw Exception() << "MatchboxAmplitude::doReshuffle(): Expecting PDG id and mass value"
<< Exception::runerror;
istringstream ins(in);
long id;
ins >> id;
if ( ins.eof() )
throw Exception() << "MatchboxAmplitude::doReshuffle(): expecting PDG id and mass value"
<< Exception::runerror;
Energy m;
ins >> iunit(m,GeV);
theReshuffleMasses[id] = m;
return "";
}
string MatchboxAmplitude::doMassless(string in) {
in = StringUtils::stripws(in);
if ( in.empty() )
throw Exception() << "MatchboxAmplitude::doMassless(): Expecting PDG id"
<< Exception::runerror;
istringstream ins(in);
long id;
ins >> id;
theReshuffleMasses[id] = ZERO;
return "";
}
string MatchboxAmplitude::doOnShell(string in) {
in = StringUtils::stripws(in);
if ( in.empty() )
throw Exception() << "MatchboxAmplitude::doOnShell(): Expecting PDG id"
<< Exception::runerror;
istringstream ins(in);
long id;
ins >> id;
tcPDPtr data = getParticleData(id);
assert(data);
theReshuffleMasses[id] = data->hardProcessMass();
return "";
}
string MatchboxAmplitude::doClearReshuffling(string) {
theReshuffleMasses.clear();
return "";
}
void MatchboxAmplitude::Init() {
static ClassDocumentation<MatchboxAmplitude> documentation
("MatchboxAmplitude is the base class for amplitude "
"implementations inside Matchbox.");
static Reference<MatchboxAmplitude,ColourBasis> interfaceColourBasis
("ColourBasis",
"Set the colour basis implementation.",
&MatchboxAmplitude::theColourBasis, false, false, true, true, false);
static Parameter<MatchboxAmplitude,int> interfaceCleanupAfter
("CleanupAfter",
"The number of points after which helicity combinations are cleaned up.",
&MatchboxAmplitude::theCleanupAfter, 20, 1, 0,
false, false, Interface::lowerlim);
interfaceCleanupAfter.rank(-1);
static Command<MatchboxAmplitude> interfaceReshuffle
("Reshuffle",
"Reshuffle the mass for the given PDG id to a different mass shell for amplitude evaluation.",
&MatchboxAmplitude::doReshuffle, false);
interfaceReshuffle.rank(-1);
static Command<MatchboxAmplitude> interfaceMassless
("Massless",
"Reshuffle the mass for the given PDG id to be massless for amplitude evaluation.",
&MatchboxAmplitude::doMassless, false);
interfaceMassless.rank(-1);
static Command<MatchboxAmplitude> interfaceOnShell
("OnShell",
"Reshuffle the mass for the given PDG id to be the on-shell mass for amplitude evaluation.",
&MatchboxAmplitude::doOnShell, false);
interfaceOnShell.rank(-1);
static Command<MatchboxAmplitude> interfaceClearReshuffling
("ClearReshuffling",
"Do not perform any reshuffling.",
&MatchboxAmplitude::doClearReshuffling, false);
interfaceClearReshuffling.rank(-1);
static Switch<MatchboxAmplitude,bool> interfaceTrivialColourLegs
("TrivialColourLegs",
"Assume the process considered has trivial colour correllations.",
&MatchboxAmplitude::theTrivialColourLegs, false, false, false);
static SwitchOption interfaceTrivialColourLegsYes
(interfaceTrivialColourLegs,
"Yes",
"",
true);
static SwitchOption interfaceTrivialColourLegsNo
(interfaceTrivialColourLegs,
"No",
"",
false);
interfaceTrivialColourLegs.rank(-1);
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeAbstractClass<MatchboxAmplitude,Amplitude>
describeMatchboxAmplitude("Herwig::MatchboxAmplitude", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Base/MatchboxAmplitude.h b/MatrixElement/Matchbox/Base/MatchboxAmplitude.h
--- a/MatrixElement/Matchbox/Base/MatchboxAmplitude.h
+++ b/MatrixElement/Matchbox/Base/MatchboxAmplitude.h
@@ -1,714 +1,706 @@
// -*- C++ -*-
//
// MatchboxAmplitude.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MatchboxAmplitude_H
#define HERWIG_MatchboxAmplitude_H
//
// This is the declaration of the MatchboxAmplitude class.
//
#include "ThePEG/MatrixElement/Amplitude.h"
#include "ThePEG/Handlers/LastXCombInfo.h"
#include "Herwig/MatrixElement/Matchbox/Utility/ColourBasis.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinCorrelationTensor.h"
#include "Herwig/MatrixElement/Matchbox/Utility/LastMatchboxXCombInfo.h"
#include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXComb.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.fh"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.fh"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief Process information with coupling order
*/
struct Process {
PDVector legs;
unsigned int orderInAlphaS;
unsigned int orderInAlphaEW;
Process()
: orderInAlphaS(0), orderInAlphaEW(0) {}
Process(const PDVector& p,
unsigned int oas,
unsigned int oae)
: legs(p), orderInAlphaS(oas), orderInAlphaEW(oae) {}
bool operator==(const Process& other) const {
return
legs == other.legs &&
orderInAlphaS == other.orderInAlphaS &&
orderInAlphaEW == other.orderInAlphaEW;
}
bool operator<(const Process& other) const {
if ( orderInAlphaS != other.orderInAlphaS )
return orderInAlphaS < other.orderInAlphaS;
if ( orderInAlphaEW != other.orderInAlphaEW )
return orderInAlphaEW < other.orderInAlphaEW;
return legs < other.legs;
}
void persistentOutput(PersistentOStream & os) const {
os << legs << orderInAlphaS << orderInAlphaEW;
}
void persistentInput(PersistentIStream & is) {
is >> legs >> orderInAlphaS >> orderInAlphaEW;
}
};
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief Enumerate the type of calculation required
*/
namespace ProcessType {
enum Types {
treeME2 = 0,
colourCorrelatedME2,
spinColourCorrelatedME2,
oneLoopInterference,
loopInducedME2,
spinCorrelatedME2
};
}
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxAmplitude is the base class for amplitude
* implementations inside Matchbox.
*
* @see \ref MatchboxAmplitudeInterfaces "The interfaces"
* defined for MatchboxAmplitude.
*/
class MatchboxAmplitude:
public Amplitude,
public LastXCombInfo<StandardXComb>,
public LastMatchboxXCombInfo {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitude();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitude();
- //@}
-
public:
/**
* Return the amplitude. Needs to be implemented from
* ThePEG::Amplitude but is actually ill-defined, as colours of the
* external particles are not specified. To this extent, this
* implementation just asserts.
*/
virtual Complex value(const tcPDVector & particles,
const vector<Lorentz5Momentum> & momenta,
const vector<int> & helicities);
/**
* Return the factory which produced this matrix element
*/
Ptr<MatchboxFactory>::tptr factory() const;
/** @name Subprocess information */
//@{
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector& p,
Ptr<MatchboxFactory>::tptr,
bool) const { return canHandle(p); }
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const { return false; }
/**
* Return the number of random numbers required to evaluate this
* amplitude at a fixed phase space point.
*/
virtual int nDimAdditional() const { return 0; }
/**
* Return a ME instance appropriate for this amplitude and the given
* subprocesses
*/
virtual Ptr<MatchboxMEBase>::ptr makeME(const PDVector&) const;
/**
* Set the (tree-level) order in \f$g_S\f$ in which this matrix
* element should be evaluated.
*/
virtual void orderInGs(unsigned int) {}
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const = 0;
/**
* Set the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element should be evaluated.
*/
virtual void orderInGem(unsigned int) {}
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const = 0;
/**
* Return the Herwig StandardModel object
*/
Ptr<StandardModel>::tcptr standardModel() {
if ( !hwStandardModel() )
hwStandardModel(dynamic_ptr_cast<Ptr<StandardModel>::tcptr>(HandlerBase::standardModel()));
return hwStandardModel();
}
/**
* Return true, if this amplitude already includes averaging over
* incoming parton's quantum numbers.
*/
virtual bool hasInitialAverage() const { return false; }
/**
* Return true, if this amplitude already includes symmetry factors
* for identical outgoing particles.
*/
virtual bool hasFinalStateSymmetry() const { return false; }
/**
* Return true, if this amplitude is handled by a BLHA one-loop provider
*/
virtual bool isOLPTree() const { return false; }
/**
* Return true, if this amplitude is handled by a BLHA one-loop provider
*/
virtual bool isOLPLoop() const { return false; }
/**
* Return true, if colour and spin correlated matrix elements should
* be ordered from the OLP
*/
virtual bool needsOLPCorrelators() const { return true; }
/**
* Write the order file header
*/
virtual void olpOrderFileHeader(ostream&) const;
/**
* Write the order file process list
*/
virtual void olpOrderFileProcesses(ostream&,
const map<pair<Process,int>,int>& procs) const;
/**
* Start the one loop provider, if appropriate, giving order and
* contract files
*/
virtual void signOLP(const string&, const string&) { }
/**
* Start the one loop provider, if appropriate
*/
virtual void startOLP(const string&, int& status) { status = -1; }
/**
* Start the one loop provider, if appropriate. This default
* implementation writes an BLHA 2.0 order file and starts the OLP
*/
virtual bool startOLP(const map<pair<Process,int>,int>& procs);
/**
* Return true, if this amplitude needs to initialize an external
* code.
*/
virtual bool isExternal() const { return false; }
/**
* Initialize this amplitude
*/
virtual bool initializeExternal() { return false; }
/**
* Return a generic process id for the given process
*/
virtual int externalId(const cPDVector&) { return 0; }
/**
* Return the map with masses to be used for amplitude evaluation
*/
const map<long,Energy>& reshuffleMasses() const { return theReshuffleMasses; }
/**
* Check if reshuffling is needed at all
*/
void checkReshuffling(Ptr<MatchboxPhasespace>::tptr);
/**
* Return true, if this amplitude makes use of amplitudeMomenta
*/
virtual bool hasAmplitudeMomenta() const { return false; }
//@}
/** @name Colour basis. */
//@{
/**
* Return the colour basis.
*/
virtual Ptr<ColourBasis>::tptr colourBasis() const { return theColourBasis; }
/**
* Return true, if the colour basis is capable of assigning colour
* flows.
*/
virtual bool haveColourFlows() const {
return colourBasis() ? colourBasis()->haveColourFlows() : false;
}
/**
* 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 an ordering identifier for the current subprocess and
* colour absis tensor index.
*/
const string& colourOrderingString(size_t id) const;
/**
* Return an ordering identifier for the current subprocess and
* colour absis tensor index.
*/
const set<vector<size_t> >& colourOrdering(size_t id) const;
//@}
/** @name Phasespace point, crossing and helicities */
//@{
/**
* Set the xcomb object.
*/
virtual void setXComb(tStdXCombPtr xc);
/**
* Return the momentum as crossed appropriate for this amplitude.
*/
Lorentz5Momentum amplitudeMomentum(int) const;
/**
* Perform a normal ordering of external legs and fill the
* crossing information as. This default implementation sorts
* lexicographically in (abs(colour)/spin/abs(charge)), putting pairs
* of particles/anti-particles where possible.
*/
virtual void fillCrossingMap(size_t shift = 0);
/**
* Generate the helicity combinations.
*/
virtual set<vector<int> > generateHelicities() const;
/**
* Return the helicity combination of the physical process in the
* conventions used by the spin correlation algorithm.
*/
virtual vector<unsigned int> physicalHelicities(const vector<int>&) const;
//@}
/** @name Tree-level amplitudes */
//@{
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Return the matrix element squared.
*/
virtual double me2() const;
/**
* Return the colour charge of a given leg
*/
double colourCharge(tcPDPtr) const;
/**
* Return the large-N charge of a given leg
*/
double largeNColourCharge(tcPDPtr) const;
/**
* Return the largeN matrix element squared.
*/
virtual double largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const;
/**
* Return the colour correlated matrix element.
*/
virtual double colourCorrelatedME2(pair<int,int> ij) const;
/**
* Return the large-N colour correlated matrix element.
*/
virtual double largeNColourCorrelatedME2(pair<int,int> ij,
Ptr<ColourBasis>::tptr largeNBasis) const;
/**
* Return true if trivial colour configuration.
*/
bool trivialColourLegs() const { return theTrivialColourLegs; }
/**
* Return true, if this amplitude is capable of consistently filling
* the rho matrices for the spin correllations
*/
virtual bool canFillRhoMatrix() const { return false; }
/**
* Return a positive helicity polarization vector for a gluon of
* momentum p (with reference vector n) to be used when evaluating
* spin correlations.
*/
virtual LorentzVector<Complex> plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n,
int id = -1) const;
/**
* Return the colour and spin correlated matrix element.
*/
virtual double spinColourCorrelatedME2(pair<int,int> emitterSpectator,
const SpinCorrelationTensor& c) const;
/**
* Return the spin correlated matrix element.
*/
virtual double spinCorrelatedME2(pair<int,int> emitterSpectator,
const SpinCorrelationTensor& c) const;
/**
* Return true, if tree-level contributions will be evaluated at amplitude level.
*/
virtual bool treeAmplitudes() const { return true; }
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&) { return 0.; }
//@}
/** @name One-loop amplitudes */
//@{
/**
* Return the one-loop amplitude, if applicable.
*/
virtual Ptr<MatchboxAmplitude>::tptr oneLoopAmplitude() const {
return Ptr<MatchboxAmplitude>::tptr();
}
/**
* Diasble one-loop functionality if not needed.
*/
virtual void disableOneLoop() {}
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Return true, if this amplitude only provides
* one-loop (QCD) corrections.
*/
virtual bool onlyOneLoop() const { return false; }
/**
* Return true, if one-loop contributions will be evaluated at amplitude level.
*/
virtual bool oneLoopAmplitudes() const { return true; }
/**
* 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 false; }
/**
* Return true, if the amplitude is DRbar renormalized, otherwise
* MSbar is assumed.
*/
virtual bool isDRbar() const { return true; }
/**
* Return true, if one loop corrections are given in the conventions
* of the integrated dipoles.
*/
virtual bool isCS() const { return false; }
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return false; }
/**
* Return true, if one loop corrections are given in the conventions
* of everything expanded.
*/
virtual bool isExpanded() const { return false; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return 0.*GeV2; }
/**
* Indicate that this amplitude is running alphas by itself.
*/
virtual bool hasRunningAlphaS() const { return false; }
/**
* Indicate that this amplitude is running alphaew by itself.
*/
virtual bool hasRunningAlphaEW() const { return false; }
/**
* If defined, return the coefficient of the pole in epsilon^2
*/
virtual double oneLoopDoublePole() const { return 0.; }
/**
* If defined, return the coefficient of the pole in epsilon
*/
virtual double oneLoopSinglePole() const { return 0.; }
/**
* Calculate the one-loop amplitudes for the phasespace point
* stored in lastXComb, if provided.
*/
virtual void prepareOneLoopAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Return the one-loop/tree interference.
*/
virtual double oneLoopInterference() const;
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluateOneLoop(size_t, const vector<int>&) { return 0.; }
//@}
/** @name Caching and helpers to setup amplitude objects. */
//@{
/**
* Flush all cashes.
*/
virtual void flushCaches() {}
/**
* Clone this amplitude.
*/
Ptr<MatchboxAmplitude>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>(clone());
}
/**
* Clone the dependencies, using a given prefix.
*/
virtual void cloneDependencies(const std::string& prefix="" , bool slim=false);
//@}
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. */
//@{
/**
* 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:
/**
* Recursively generate helicities
*/
void doGenerateHelicities(set<vector<int> >& res,
vector<int>& current,
size_t pos) const;
/**
* The colour basis implementation to be used.
*/
Ptr<ColourBasis>::ptr theColourBasis;
/**
* The number of points after which helicity combinations wil be
* cleaned up
*/
int theCleanupAfter;
/**
* The number of points that are calculated before a certain
* helicity is excluded. Needed in pp->V
*/
int treeLevelHelicityPoints;
/**
* The number of points that are calculated before a certain
* helicity is excluded. Needed in pp->V
*/
int oneLoopHelicityPoints;
/**
* The map with masses to be used for amplitude evaluation
*/
map<long,Energy> theReshuffleMasses;
/**
* True if trivial colour configuration.
*/
bool theTrivialColourLegs;
/**
* A command to fill the reshuffle mass map
*/
string doReshuffle(string);
/**
* A command to fill the reshuffle mass map
*/
string doMassless(string);
/**
* A command to fill the reshuffle mass map
*/
string doOnShell(string);
/**
* Clear the reshuffling map
*/
string doClearReshuffling(string);
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitude & operator=(const MatchboxAmplitude &) = delete;
};
inline PersistentOStream& operator<<(PersistentOStream& os,
const Process& h) {
h.persistentOutput(os);
return os;
}
inline PersistentIStream& operator>>(PersistentIStream& is,
Process& h) {
h.persistentInput(is);
return is;
}
}
#endif /* HERWIG_MatchboxAmplitude_H */
diff --git a/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.cc b/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.cc
--- a/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.cc
+++ b/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.cc
@@ -1,238 +1,236 @@
// -*- C++ -*-
//
// MatchboxHybridAmplitude.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MatchboxHybridAmplitude class.
//
#include "MatchboxHybridAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
using namespace Herwig;
MatchboxHybridAmplitude::MatchboxHybridAmplitude()
: theUseOLPCorrelators(false) {}
-MatchboxHybridAmplitude::~MatchboxHybridAmplitude() {}
-
IBPtr MatchboxHybridAmplitude::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxHybridAmplitude::fullclone() const {
return new_ptr(*this);
}
bool MatchboxHybridAmplitude::isConsistent() const {
assert(oneLoopAmplitude());
return
!treeLevelAmplitude()->isOLPTree() &&
!treeLevelAmplitude()->isOLPLoop() &&
oneLoopAmplitude()->haveOneLoop() &&
treeLevelAmplitude()->orderInGs() ==
oneLoopAmplitude()->orderInGs() &&
treeLevelAmplitude()->orderInGem() ==
oneLoopAmplitude()->orderInGem() &&
treeLevelAmplitude()->hasRunningAlphaS() ==
oneLoopAmplitude()->hasRunningAlphaS() &&
treeLevelAmplitude()->hasRunningAlphaEW() ==
oneLoopAmplitude()->hasRunningAlphaEW() &&
!(treeLevelAmplitude()->nDimAdditional() != 0 &&
oneLoopAmplitude()->nDimAdditional() != 0);
}
bool MatchboxHybridAmplitude::canHandle(const PDVector& p,
Ptr<MatchboxFactory>::tptr f,
bool virt) const {
if ( !virt )
return treeLevelAmplitude()->canHandle(p,f,false);
if ( treeLevelAmplitude()->canHandle(p,f,false) &&
oneLoopAmplitude()->canHandle(p,f,true) ) {
if ( !isConsistent() ) {
generator()->log() << "Warning: Inconsistent settings encountered for MatchboxHybridAmplitude '"
<< name() << "'\n" << flush;
return false;
}
return true;
}
return false;
}
void MatchboxHybridAmplitude::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
treeLevelAmplitude()->prepareAmplitudes(me);
}
void MatchboxHybridAmplitude::prepareOneLoopAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
assert(oneLoopAmplitude());
oneLoopAmplitude()->prepareOneLoopAmplitudes(me);
}
double MatchboxHybridAmplitude::symmetryRatio() const {
assert(oneLoopAmplitude());
double ifact = 1.;
if ( treeLevelAmplitude()->hasInitialAverage() &&
!oneLoopAmplitude()->hasInitialAverage() ) {
ifact = 1./4.;
if (lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour3 ||
lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour3bar )
ifact /= SM().Nc();
else if ( lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour8 )
ifact /= (SM().Nc()*SM().Nc()-1.);
if ( lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour3 ||
lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour3bar )
ifact /= SM().Nc();
else if ( mePartonData()[1]->iColour() == PDT::Colour8 )
ifact /= (SM().Nc()*SM().Nc()-1.);
}
if ( !treeLevelAmplitude()->hasInitialAverage() &&
oneLoopAmplitude()->hasInitialAverage() ) {
ifact = 4.;
if ( lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour3 ||
lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour3bar )
ifact *= SM().Nc();
else if ( lastMatchboxXComb()->matchboxME()->mePartonData()[0]->iColour() == PDT::Colour8 )
ifact *= (SM().Nc()*SM().Nc()-1.);
if ( lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour3 ||
lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour3bar )
ifact *= SM().Nc();
else if ( lastMatchboxXComb()->matchboxME()->mePartonData()[1]->iColour() == PDT::Colour8 )
ifact *= (SM().Nc()*SM().Nc()-1.);
}
if ( treeLevelAmplitude()->hasFinalStateSymmetry() &&
!oneLoopAmplitude()->hasFinalStateSymmetry() ) {
assert(lastMatchboxXComb()->matchboxME());
ifact *= lastMatchboxXComb()->matchboxME()->finalStateSymmetry();
}
if ( !treeLevelAmplitude()->hasFinalStateSymmetry() &&
oneLoopAmplitude()->hasFinalStateSymmetry() ) {
assert(lastMatchboxXComb()->matchboxME());
ifact /= lastMatchboxXComb()->matchboxME()->finalStateSymmetry();
}
return ifact;
}
void MatchboxHybridAmplitude::cloneDependencies(const std::string& prefix,bool slim) {
if ( treeLevelAmplitude() ) {
Ptr<MatchboxAmplitude>::ptr myTreeLevelAmplitude = treeLevelAmplitude()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myTreeLevelAmplitude->name();
if ( ! (generator()->preinitRegister(myTreeLevelAmplitude,pname.str()) ) )
throw Exception() << "MatchboxHybridAmplitude::cloneDependencies(): Amplitude " << pname.str() << " already existing." << Exception::runerror;
myTreeLevelAmplitude->cloneDependencies(pname.str());
treeLevelAmplitude(myTreeLevelAmplitude);
}
if ( oneLoopAmplitude() ) {
Ptr<MatchboxAmplitude>::ptr myOneLoopAmplitude = oneLoopAmplitude()->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myOneLoopAmplitude->name();
if ( ! (generator()->preinitRegister(myOneLoopAmplitude,pname.str()) ) )
throw Exception() << "MatchboxHybridAmplitude::cloneDependencies(): Amplitude " << pname.str() << " already existing." << Exception::runerror;
myOneLoopAmplitude->cloneDependencies(pname.str());
oneLoopAmplitude(myOneLoopAmplitude);
}
MatchboxAmplitude::cloneDependencies(prefix,slim);
}
void MatchboxHybridAmplitude::doinit() {
MatchboxAmplitude::doinit();
if ( treeLevelAmplitude() )
treeLevelAmplitude()->init();
if ( oneLoopAmplitude() )
oneLoopAmplitude()->init();
}
void MatchboxHybridAmplitude::doinitrun() {
MatchboxAmplitude::doinitrun();
if ( treeLevelAmplitude() )
treeLevelAmplitude()->initrun();
if ( oneLoopAmplitude() )
oneLoopAmplitude()->initrun();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxHybridAmplitude::persistentOutput(PersistentOStream & os) const {
os << theTreeLevelAmplitude << theOneLoopAmplitude << theUseOLPCorrelators;
}
void MatchboxHybridAmplitude::persistentInput(PersistentIStream & is, int) {
is >> theTreeLevelAmplitude >> theOneLoopAmplitude >> theUseOLPCorrelators;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxHybridAmplitude,Herwig::MatchboxAmplitude>
describeHerwigMatchboxHybridAmplitude("Herwig::MatchboxHybridAmplitude", "Herwig.so");
void MatchboxHybridAmplitude::Init() {
static ClassDocumentation<MatchboxHybridAmplitude> documentation
("MatchboxHybridAmplitude unifies two amplitude objects to "
"provide tree and one-loop matrix elements.");
static Reference<MatchboxHybridAmplitude,MatchboxAmplitude> interfaceTreeLevelAmplitude
("TreeLevelAmplitude",
"Set the tree level amplitude to be used.",
&MatchboxHybridAmplitude::theTreeLevelAmplitude, false, false, true, false, false);
static Reference<MatchboxHybridAmplitude,MatchboxAmplitude> interfaceOneLoopAmplitude
("OneLoopAmplitude",
"Set the one-loop amplitude to be used.",
&MatchboxHybridAmplitude::theOneLoopAmplitude, false, false, true, true, false);
static Switch<MatchboxHybridAmplitude,bool> interfaceUseOLPCorrelators
("UseOLPCorrelators",
"Obtain correlated matrix elements from the OLP instead of "
"the tree-level amplitude.",
&MatchboxHybridAmplitude::theUseOLPCorrelators, false, false, false);
static SwitchOption interfaceUseOLPCorrelatorsYes
(interfaceUseOLPCorrelators,
"Yes",
"",
true);
static SwitchOption interfaceUseOLPCorrelatorsNo
(interfaceUseOLPCorrelators,
"No",
"",
false);
interfaceUseOLPCorrelators.rank(-1);
}
diff --git a/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.h b/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.h
--- a/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.h
+++ b/MatrixElement/Matchbox/Base/MatchboxHybridAmplitude.h
@@ -1,637 +1,629 @@
// -*- C++ -*-
//
// MatchboxHybridAmplitude.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxHybridAmplitude_H
#define Herwig_MatchboxHybridAmplitude_H
//
// This is the declaration of the MatchboxHybridAmplitude class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxHybridAmplitude unifies two amplitude objects to
* provide tree and one-loop matrix elements.
*
* @see \ref MatchboxHybridAmplitudeInterfaces "The interfaces"
* defined for MatchboxHybridAmplitude.
*/
class MatchboxHybridAmplitude: public Herwig::MatchboxAmplitude {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxHybridAmplitude();
- /**
- * The destructor.
- */
- virtual ~MatchboxHybridAmplitude();
- //@}
-
public:
/**
* Return the amplitude object to provide tree-level amplitudes.
*/
Ptr<MatchboxAmplitude>::tptr treeLevelAmplitude() const { return theTreeLevelAmplitude; }
/**
* Set the amplitude object to provide tree-level amplitudes.
*/
void treeLevelAmplitude(Ptr<MatchboxAmplitude>::tptr amp) { theTreeLevelAmplitude = amp; }
/**
* Return the amplitude object to provide one-loop amplitudes.
*/
virtual Ptr<MatchboxAmplitude>::tptr oneLoopAmplitude() const { return theOneLoopAmplitude; }
/**
* Set the amplitude object to provide one-loop amplitudes.
*/
void oneLoopAmplitude(Ptr<MatchboxAmplitude>::tptr amp) { theOneLoopAmplitude = amp; }
/**
* Return true, if the two amplitude objects can be used in a
* consistent way.
*/
bool isConsistent() const;
public:
/** @name Subprocess information */
//@{
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector& p,
Ptr<MatchboxFactory>::tptr f,
bool virt) const;
/**
* Return the number of random numbers required to evaluate this
* amplitude at a fixed phase space point.
*/
virtual int nDimAdditional() const {
if ( !oneLoopAmplitude() )
return treeLevelAmplitude()->nDimAdditional();
return
treeLevelAmplitude()->nDimAdditional() ?
treeLevelAmplitude()->nDimAdditional() :
oneLoopAmplitude()->nDimAdditional();
}
/**
* Return a ME instance appropriate for this amplitude and the given
* subprocesses
*/
virtual Ptr<MatchboxMEBase>::ptr makeME(const PDVector& p) const {
return treeLevelAmplitude()->makeME(p);
}
/**
* Set the (tree-level) order in \f$g_S\f$ in which this matrix
* element should be evaluated.
*/
virtual void orderInGs(unsigned int n) {
treeLevelAmplitude()->orderInGs(n);
if ( oneLoopAmplitude() )
oneLoopAmplitude()->orderInGs(n);
}
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const {
return treeLevelAmplitude()->orderInGs();
}
/**
* Set the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element should be evaluated.
*/
virtual void orderInGem(unsigned int n) {
treeLevelAmplitude()->orderInGem(n);
if ( oneLoopAmplitude() )
oneLoopAmplitude()->orderInGem(n);
}
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const {
return treeLevelAmplitude()->orderInGem();
}
/**
* Return true, if this amplitude already includes averaging over
* incoming parton's quantum numbers.
*/
virtual bool hasInitialAverage() const {
return treeLevelAmplitude()->hasInitialAverage();
}
/**
* Return true, if this amplitude already includes symmetry factors
* for identical outgoing particles.
*/
virtual bool hasFinalStateSymmetry() const {
return treeLevelAmplitude()->hasFinalStateSymmetry();
}
/**
* Return true, if this amplitude is handled by a BLHA one-loop provider
*/
virtual bool isOLPTree() const { return false; }
/**
* Return true, if this amplitude is handled by a BLHA one-loop provider
*/
virtual bool isOLPLoop() const {
if ( !oneLoopAmplitude() )
return false;
return oneLoopAmplitude()->isOLPLoop();
}
/**
* Return true, if colour and spin correlated matrix elements should
* be ordered from the OLP
*/
virtual bool needsOLPCorrelators() const {
return theUseOLPCorrelators;
}
/**
* Start the one loop provider, if appropriate. This default
* implementation writes an BLHA 2.0 order file and starts the OLP
*/
virtual bool startOLP(const map<pair<Process,int>,int>& procs) {
assert(oneLoopAmplitude());
return oneLoopAmplitude()->startOLP(procs);
}
/**
* Return true, if this amplitude needs to initialize an external
* code.
*/
virtual bool isExternal() const {
return treeLevelAmplitude()->isExternal();
}
/**
* Initialize this amplitude
*/
virtual bool initializeExternal() {
return treeLevelAmplitude()->initializeExternal();
}
/**
* Return a generic process id for the given process
*/
virtual int externalId(const cPDVector& proc) {
return treeLevelAmplitude()->externalId(proc);
}
//@}
/** @name Colour basis. */
//@{
/**
* Return the colour basis.
*/
virtual Ptr<ColourBasis>::tptr colourBasis() const {
return treeLevelAmplitude()->colourBasis();
}
/**
* Return true, if the colour basis is capable of assigning colour
* flows.
*/
virtual bool haveColourFlows() const {
return treeLevelAmplitude()->haveColourFlows();
}
/**
* 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 treeLevelAmplitude()->colourGeometries(diag);
}
//@}
/** @name Phasespace point, crossing and helicities */
//@{
/**
* Set the xcomb object.
*/
virtual void setXComb(tStdXCombPtr xc) {
treeLevelAmplitude()->setXComb(xc);
if ( oneLoopAmplitude() )
oneLoopAmplitude()->setXComb(xc);
lastMatchboxXComb(xc);
}
/**
* Perform a normal ordering of external legs and fill the
* crossing information as. This default implementation sorts
* lexicographically in (abs(colour)/spin/abs(charge)), putting pairs
* of particles/anti-particles where possible.
*/
virtual void fillCrossingMap(size_t shift = 0) {
treeLevelAmplitude()->fillCrossingMap(shift);
}
//@}
/** @name Tree-level amplitudes */
//@{
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Return the matrix element squared.
*/
virtual double me2() const {
return treeLevelAmplitude()->me2();
}
/**
* Return the largeN matrix element squared.
*/
virtual double largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const {
return treeLevelAmplitude()->largeNME2(largeNBasis);
}
/**
* Return the colour correlated matrix element.
*/
virtual double colourCorrelatedME2(pair<int,int> ij) const {
return
theUseOLPCorrelators ?
oneLoopAmplitude()->colourCorrelatedME2(ij) :
treeLevelAmplitude()->colourCorrelatedME2(ij);
}
/**
* Return the large-N colour correlated matrix element.
*/
virtual double largeNColourCorrelatedME2(pair<int,int> ij,
Ptr<ColourBasis>::tptr largeNBasis) const {
return treeLevelAmplitude()->largeNColourCorrelatedME2(ij,largeNBasis);
}
/**
* Return a positive helicity polarization vector for a gluon of
* momentum p (with reference vector n) to be used when evaluating
* spin correlations.
*/
virtual LorentzVector<Complex> plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n,
int id = -1) const {
return
theUseOLPCorrelators ?
oneLoopAmplitude()->plusPolarization(p,n,id) :
treeLevelAmplitude()->plusPolarization(p,n,id);
}
/**
* Return the colour and spin correlated matrix element.
*/
virtual double spinColourCorrelatedME2(pair<int,int> emitterSpectator,
const SpinCorrelationTensor& c) const {
return
theUseOLPCorrelators ?
oneLoopAmplitude()->spinColourCorrelatedME2(emitterSpectator,c) :
treeLevelAmplitude()->spinColourCorrelatedME2(emitterSpectator,c);
}
/**
* Return the spin correlated matrix element.
*/
virtual double spinCorrelatedME2(pair<int,int> emitterSpectator,
const SpinCorrelationTensor& c) const {
return
theUseOLPCorrelators ?
oneLoopAmplitude()->spinCorrelatedME2(emitterSpectator,c) :
treeLevelAmplitude()->spinCorrelatedME2(emitterSpectator,c);
}
/**
* Return true, if this amplitude is capable of consistently filling
* the rho matrices for the spin correllations
*/
virtual bool canFillRhoMatrix() const {
return treeLevelAmplitude()->canFillRhoMatrix();
}
/**
* Return the helicity combination of the physical process in the
* conventions used by the spin correlation algorithm.
*/
virtual vector<unsigned int> physicalHelicities(const vector<int>& hel) const {
return treeLevelAmplitude()->physicalHelicities(hel);
}
/**
* Return true, if tree-level contributions will be evaluated at amplitude level.
*/
virtual bool treeAmplitudes() const {
return treeLevelAmplitude()->treeAmplitudes();
}
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t a, const vector<int>& hel, Complex& largeN) {
return treeLevelAmplitude()->evaluate(a,hel,largeN);
}
//@}
/** @name One-loop amplitudes */
//@{
/**
* Diasble one-loop functionality if not needed.
*/
virtual void disableOneLoop() { oneLoopAmplitude(Ptr<MatchboxAmplitude>::ptr()); }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return oneLoopAmplitude(); }
/**
* Return true, if this amplitude only provides
* one-loop (QCD) corrections.
*/
virtual bool onlyOneLoop() const { return false; }
/**
* Return true, if one-loop contributions will be evaluated at amplitude level.
*/
virtual bool oneLoopAmplitudes() const {
assert(oneLoopAmplitude());
return oneLoopAmplitude()->oneLoopAmplitudes();
}
/**
* Return true, if the amplitude is DRbar renormalized, otherwise
* MSbar is assumed.
*/
virtual bool isDRbar() const {
assert(oneLoopAmplitude());
return oneLoopAmplitude()->isDRbar();
}
/**
* 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 {
assert(oneLoopAmplitude());
return oneLoopAmplitude()->isDR();
}
/**
* Return true, if one loop corrections are given in the conventions
* of the integrated dipoles.
*/
virtual bool isCS() const {
assert(oneLoopAmplitude());
return oneLoopAmplitude()->isCS();
}
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const {
assert(oneLoopAmplitude());
return oneLoopAmplitude()->isBDK();
}
/**
* Return true, if one loop corrections are given in the conventions
* of everything expanded.
*/
virtual bool isExpanded() const {
assert(oneLoopAmplitude());
return oneLoopAmplitude()->isExpanded();
}
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const {
assert(oneLoopAmplitude());
return oneLoopAmplitude()->mu2();
}
/**
* Adjust the virtual symmetry factor conventions to the tree level
* one
*/
double symmetryRatio() const;
/**
* Indicate that this amplitude is running alphas by itself.
*/
virtual bool hasRunningAlphaS() const {
return treeLevelAmplitude()->hasRunningAlphaS();
}
/**
* Indicate that this amplitude is running alphaew by itself.
*/
virtual bool hasRunningAlphaEW() const {
return treeLevelAmplitude()->hasRunningAlphaEW();
}
/**
* If defined, return the coefficient of the pole in epsilon^2
*/
virtual double oneLoopDoublePole() const {
assert(oneLoopAmplitude());
return symmetryRatio()*oneLoopAmplitude()->oneLoopDoublePole();
}
/**
* If defined, return the coefficient of the pole in epsilon
*/
virtual double oneLoopSinglePole() const {
assert(oneLoopAmplitude());
return symmetryRatio()*oneLoopAmplitude()->oneLoopSinglePole();
}
/**
* Calculate the one-loop amplitudes for the phasespace point
* stored in lastXComb, if provided.
*/
virtual void prepareOneLoopAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Return the one-loop/tree interference.
*/
virtual double oneLoopInterference() const {
assert(oneLoopAmplitude());
return symmetryRatio()*oneLoopAmplitude()->oneLoopInterference();
}
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluateOneLoop(size_t a, const vector<int>& hel) {
assert(oneLoopAmplitude());
return oneLoopAmplitude()->evaluateOneLoop(a,hel);
}
//@}
/** @name Caching and helpers to setup amplitude objects. */
//@{
/**
* Flush all cashes.
*/
virtual void flushCaches() {
treeLevelAmplitude()->flushCaches();
if ( oneLoopAmplitude() )
oneLoopAmplitude()->flushCaches();
}
/**
* Clone the dependencies, using a given prefix.
*/
virtual void cloneDependencies(const std::string& prefix= "" , bool slim=false);
//@}
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();
//@}
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 amplitude object to provide tree-level amplitudes.
*/
Ptr<MatchboxAmplitude>::ptr theTreeLevelAmplitude;
/**
* The amplitude object to provide one-loop amplitudes.
*/
Ptr<MatchboxAmplitude>::ptr theOneLoopAmplitude;
/**
* True, if correlators should be used from the OLP amplitude
*/
bool theUseOLPCorrelators;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxHybridAmplitude & operator=(const MatchboxHybridAmplitude &) = delete;
};
}
#endif /* Herwig_MatchboxHybridAmplitude_H */
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,1680 +1,1678 @@
// -*- C++ -*-
//
// MatchboxMEBase.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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/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/MatrixElement/Matchbox/Base/MergerBase.h"
#include "Herwig/API/RunDirectories.h"
#include "Herwig/MatrixElement/ProductionMatrixElement.h"
#include "Herwig/MatrixElement/HardVertex.h"
#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) {}
-MatchboxMEBase::~MatchboxMEBase() {}
-
Ptr<MatchboxFactory>::tptr MatchboxMEBase::factory() const {
return MatchboxFactory::currentFactory();
}
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<long> MatchboxMEBase::getNLightJetVec() const { return factory()->nLightJetVec(); }
vector<long> MatchboxMEBase::getNHeavyJetVec() const { return factory()->nHeavyJetVec(); }
vector<long> 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 (auto const & d : diags )
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 ( auto const & fit : cflows)
flows.push_back(new ColourLines(ColourBasis::cfstring(fit)));
}
Selector<const ColourLines *> res;
for ( auto const & f : flows ) 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 ( auto const & p : sub->outgoing() ) {
out.push_back(p->data().iSpin());
hard.push_back(p);
}
// 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 ( auto const & p : sub->outgoing() )
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){
theMerger->setME(this);
theMerger->setXComb( xc );
}
}
double MatchboxMEBase::generateIncomingPartons(const double* r1, const double* r2) {
// shamelessly stolen from PartonExtractor.cc
Energy2 shmax = lastCuts().sHatMax();
Energy2 shmin = lastCuts().sHatMin();
Energy2 sh = shmin*pow(shmax/shmin, *r1);
double ymax = lastCuts().yHatMax();
double ymin = lastCuts().yHatMin();
double km = log(shmax/shmin);
ymax = min(ymax, log(lastCuts().x1Max()*sqrt(lastS()/sh)));
ymin = max(ymin, -log(lastCuts().x2Max()*sqrt(lastS()/sh)));
double y = ymin + (*r2)*(ymax - ymin);
double x1 = exp(-0.5*log(lastS()/sh) + y);
double x2 = exp(-0.5*log(lastS()/sh) - y);
Lorentz5Momentum P1 = lastParticles().first->momentum();
LorentzMomentum p1 = lightCone((P1.rho() + P1.e())*x1, Energy());
p1.rotateY(P1.theta());
p1.rotateZ(P1.phi());
meMomenta()[0] = p1;
Lorentz5Momentum P2 = lastParticles().second->momentum();
LorentzMomentum p2 = lightCone((P2.rho() + P2.e())*x2, Energy());
p2.rotateY(P2.theta());
p2.rotateZ(P2.phi());
meMomenta()[1] = p2;
lastXCombPtr()->lastX1X2(make_pair(x1,x2));
lastXCombPtr()->lastSHat((meMomenta()[0]+meMomenta()[1]).m2());
return km*(ymax - ymin);
}
bool MatchboxMEBase::generateKinematics(const double * r) {
if ( phasespace() ) {
jacobian(phasespace()->generateKinematics(r,meMomenta()));
if ( jacobian() == 0.0 )
return false;
setScale();
if (theMerger&&!theMerger->generateKinematics(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 ( auto const & v : virtuals() ) {
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 ( auto const & c : counts) {
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 {
double fac = 1.;
if ( !hasInitialAverage() ) {
for ( size_t k = 0; k < 2; ++k ) {
// Spin 0 does not involve any additional factors
if ( mePartonData()[k]->iSpin() == PDT::Spin1Half )
fac *= 1./2.;
else if ( mePartonData()[k]->iSpin() == PDT::Spin1 &&
mePartonData()[k]->hardProcessMass() == ZERO )
fac *= 1./2.;
else if ( mePartonData()[k]->iSpin() == PDT::Spin1 &&
mePartonData()[k]->hardProcessMass() > ZERO )
fac *= 1./3.;
else if ( mePartonData()[k]->iSpin() == PDT::Spin3Half )
fac *= 1./4.;
else if ( mePartonData()[k]->iSpin() == PDT::Spin2 &&
mePartonData()[k]->hardProcessMass() == ZERO )
fac *= 1./2.;
else if ( mePartonData()[k]->iSpin() == PDT::Spin2 &&
mePartonData()[k]->hardProcessMass() > ZERO )
fac *= 1./5.;
}
}
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::prefactor()const{
return (sqr(hbarc)/(2.*lastSHat())) *jacobian()* lastMEPDFWeight();
}
CrossSection MatchboxMEBase::dSigHatDRB() const {
getPDFWeight();
lastME2(me2());
return oneLoopNoBorn()?ZERO:prefactor() * lastME2();
}
CrossSection MatchboxMEBase::dSigHatDRV() const {
getPDFWeight();
lastME2(me2());
return ( oneLoop() && !oneLoopNoLoops() )?(prefactor() * oneLoopInterference()):ZERO;
}
CrossSection MatchboxMEBase::dSigHatDRI() const {
getPDFWeight();
lastME2(me2());
CrossSection res=ZERO;
if (oneLoop() &&!onlyOneLoop()) {
for ( auto const & v : virtuals()) {
v->setXComb(lastXCombPtr());
res += v->dSigHatDR();
}
if ( checkPoles() && oneLoop() )
logPoles();
}
return res;
}
CrossSection MatchboxMEBase::dSigHatDRAlphaDiff(double alpha) const {
getPDFWeight();
lastME2(me2());
CrossSection res=ZERO;
for ( auto const & v: virtuals() ) {
v->setXComb(lastXCombPtr());
res+=v->dSigHatDRAlphaDiff( alpha);
}
return res;
}
CrossSection MatchboxMEBase::dSigHatDR() const {
getPDFWeight();
if (theMerger){
lastMECrossSection(theMerger->MergingDSigDR());
return lastMECrossSection();
}
else if (lastXCombPtr()->willPassCuts() ) {
lastME2(me2());
CrossSection _dSigHatDRB, _dSigHatDRV, _dSigHatDRI, res = ZERO;
// ----- dSigHatDRB -----
_dSigHatDRB = oneLoopNoBorn()?ZERO:prefactor() * lastME2();
// ----- dSigHatDRV -----
_dSigHatDRV = ( oneLoop() && !oneLoopNoLoops() )?(prefactor() * oneLoopInterference()):ZERO;
// ----- dSigHatDRI -----
if (oneLoop() &&!onlyOneLoop()) {
for ( auto const & v : virtuals()) {
v->setXComb(lastXCombPtr());
res += v->dSigHatDR();
}
if ( checkPoles() && oneLoop() )
logPoles();
}
_dSigHatDRI = res;
// ----- finalizing -----
lastMECrossSection(_dSigHatDRB + _dSigHatDRV + _dSigHatDRI);
return lastMECrossSection();
}
else
{
lastME2(ZERO);
lastMECrossSection(ZERO);
return lastMECrossSection();
}
}
double MatchboxMEBase::oneLoopInterference() const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->oneLoopAmplitudes() )
matchboxAmplitude()->prepareOneLoopAmplitudes(this);
double res =
matchboxAmplitude()->oneLoopInterference()*
me2Norm(1);
return res;
}
throw Exception()
<< "MatchboxMEBase::oneLoopInterference() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
MatchboxMEBase::AccuracyHistogram::AccuracyHistogram(double low,
double up,
unsigned int nbins)
: lower(low), upper(up),
sameSign(0), oppositeSign(0), nans(0),
overflow(0), underflow(0) {
double step = (up-low)/nbins;
for ( unsigned int k = 1; k <= nbins; ++k )
bins[lower + k*step] = 0.0;
}
void MatchboxMEBase::AccuracyHistogram::book(double a, double b) {
if ( ! (isfinite(a) && isfinite(b)) ) {
++nans;
return;
}
if ( a*b >= 0. )
++sameSign;
if ( a*b < 0. )
++oppositeSign;
double r = 1.;
if ( abs(a) != 0.0 )
r = abs(1.-abs(b/a));
else if ( abs(b) != 0.0 )
r = abs(b);
if ( log10(r) < lower || r == 0.0 ) {
++underflow;
return;
}
if ( log10(r) > upper ) {
++overflow;
return;
}
map<double,double>::iterator bin =
bins.upper_bound(log10(r));
if ( bin == bins.end() )
return;
bin->second += 1.;
}
void MatchboxMEBase::AccuracyHistogram::dump(const std::string& folder, const std::string& prefix,
const cPDVector& proc) const {
ostringstream fname("");
for ( cPDVector::const_iterator p = proc.begin();
p != proc.end(); ++p )
fname << (**p).PDGName();
ofstream out((folder+"/"+prefix+fname.str()+".dat").c_str());
out << "# same sign : " << sameSign << " opposite sign : "
<< oppositeSign << " nans : " << nans
<< " overflow : " << overflow
<< " underflow : " << underflow << "\n";
for ( map<double,double>::const_iterator b = bins.begin();
b != bins.end(); ++b ) {
map<double,double>::const_iterator bp = b; --bp;
if ( b->second != 0. ) {
if ( b != bins.begin() )
out << bp->first;
else
out << lower;
out << " " << b->first
<< " " << b->second
<< "\n" << flush;
}
}
ofstream gpout((folder+"/"+prefix+fname.str()+".gp").c_str());
gpout << "set terminal png\n"
<< "set xlabel 'accuracy of pole cancellation [decimal places]'\n"
<< "set ylabel 'counts\n"
<< "set xrange [-20:0]\n"
<< "set output '" << prefix << fname.str() << ".png'\n"
<< "plot '" << prefix << fname.str() << ".dat' using (0.5*($1+$2)):3 with linespoints pt 7 ps 1 not";
}
void MatchboxMEBase::AccuracyHistogram::persistentOutput(PersistentOStream& os) const {
os << lower << upper << bins
<< sameSign << oppositeSign << nans
<< overflow << underflow;
}
void MatchboxMEBase::AccuracyHistogram::persistentInput(PersistentIStream& is) {
is >> lower >> upper >> bins
>> sameSign >> oppositeSign >> nans
>> overflow >> underflow;
}
void MatchboxMEBase::logPoles() const {
double res2me = oneLoopDoublePole();
double res1me = oneLoopSinglePole();
double res2i = 0.;
double res1i = 0.;
for ( auto const & v : virtuals()) {
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<SubtractionDipolePtr>
MatchboxMEBase::getDipoles(const vector<SubtractionDipolePtr>& dipoles,
const vector<MatchboxMEBasePtr> & borns,bool slim) const {
vector<SubtractionDipolePtr> 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<SubtractionDipolePtr> matchDipoles;
for ( auto const & d : dipoles ) {
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<SubtractionDipolePtr> matchDipoles2;
for ( auto const & d : matchDipoles ) {
if ( !d->canHandleSplitting(rep,emitter,emission) )
continue;
matchDipoles2.push_back(d);
}
if ( matchDipoles2.empty() )
continue;
map<Ptr<DiagramBase>::ptr,SubtractionDipole::MergeInfo> mergeInfo;
for ( auto const & d : diagrams() ) {
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<SubtractionDipolePtr> matchDipoles3;
for ( auto const & d : matchDipoles2 ) {
if ( ! d->canHandleSpectator(rep,spectator) )
continue;
matchDipoles3.push_back(d);
}
if ( matchDipoles3.empty() )
continue;
if ( noDipole(emitter,emission,spectator) )
continue;
for ( auto const & d : matchDipoles3 ) {
if ( !d->canHandle(rep,emitter,emission,spectator) )
continue;
for ( auto const & b : borns ) {
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->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 << ".virtual" << "." ;
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 ( auto const & rw : factory()->reweighters())
nDipole->addReweighter(rw);
}
if ( !factory()->preweighters().empty() ) {
for ( auto const & rw : factory()->preweighters() )
nDipole->addPreweighter(rw);
}
nDipole->cloneDependencies(dname.str(),slim);
}
}
}
}
}
}
vector<Ptr<SubtractionDipole>::tptr> partners;
copy(res.begin(),res.end(),back_inserter(partners));
for ( auto const & d : res )
d->partnerDipoles(partners);
return res;
}
double MatchboxMEBase::colourCorrelatedME2(pair<int,int> ij) const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
double res =
matchboxAmplitude()->colourCorrelatedME2(ij)*
me2Norm();
return res;
}
throw Exception()
<< "MatchboxMEBase::colourCorrelatedME2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
double MatchboxMEBase::largeNColourCorrelatedME2(pair<int,int> ij,
Ptr<ColourBasis>::tptr largeNBasis) const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->treeAmplitudes() ) {
largeNBasis->prepare(mePartonData(),false);
matchboxAmplitude()->prepareAmplitudes(this);
}
double res =
matchboxAmplitude()->largeNColourCorrelatedME2(ij,largeNBasis)*
me2Norm();
return res;
}
throw Exception()
<< "MatchboxMEBase::largeNColourCorrelatedME2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
double MatchboxMEBase::spinColourCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
double res =
matchboxAmplitude()->spinColourCorrelatedME2(ij,c)*
me2Norm();
return res;
}
throw Exception()
<< "MatchboxMEBase::spinColourCorrelatedME2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
double MatchboxMEBase::spinCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
if ( matchboxAmplitude() ) {
if ( matchboxAmplitude()->treeAmplitudes() )
matchboxAmplitude()->prepareAmplitudes(this);
double res =
matchboxAmplitude()->spinCorrelatedME2(ij,c)*
me2Norm();
return res;
}
throw Exception()
<< "MatchboxMEBase::spinCorrelatedME2() expects a MatchboxAmplitude object.\n"
<< "Please check your setup." << Exception::runerror;
return 0.;
}
void MatchboxMEBase::flushCaches() {
if ( theMerger )theMerger->flushCaches();
MEBase::flushCaches();
if ( matchboxAmplitude() )
matchboxAmplitude()->flushCaches();
for ( auto const & r : reweights() )
r->flushCaches();
for ( auto const & v : virtuals())
v->flushCaches();
}
void MatchboxMEBase::setKinematics() {
MEBase::setKinematics();
if ( theMerger )
theMerger->setKinematics();
}
void MatchboxMEBase::clearKinematics() {
MEBase::clearKinematics();
if ( theMerger )
theMerger->clearKinematics();
}
const MergerBasePtr MatchboxMEBase::merger() const {
return theMerger;
}
MergerBasePtr MatchboxMEBase::merger() {
return theMerger;
}
void MatchboxMEBase::merger(MergerBasePtr v) {
theMerger = v;
}
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 ( auto & rw : theReweights ) {
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 ( auto & v : virtuals()) {
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 ( auto const & v : virtuals() )
insertionAdd = max(insertionAdd,v->nDimAdditional());
xc.nDimInsertions(insertionAdd);
xc.nLight(getNLight());
if(xc.nLightJetVec().empty())
for (auto const & id : getNLightJetVec())
xc.nLightJetVec( id );
if(xc.nHeavyJetVec().empty())
for (auto const & id :getNHeavyJetVec())
xc.nHeavyJetVec(id);
if(xc.nLightProtonVec().empty())
for (auto const & id : getNLightProtonVec())
xc.nLightProtonVec(id);
xc.olpId(olpProcess());
if ( initVerbose() ) {
ostringstream fname_strm;
// only allow alphanumeric, / and _ in filename
for (const char c : name()) {
switch (c) {
case '+' : fname_strm << "+"; break;
case '-' : fname_strm << "-"; break;
case '~' : fname_strm << "_tilde"; break;
case ']' : break;
case ',' : fname_strm << "__"; break;
default : fname_strm << (isalnum(c) ? c : '_'); break;
}
}
fname_strm << ".diagrams";
const string fname = fname_strm.str();
ifstream test(fname.c_str());
if ( !test ) {
test.close();
ofstream out(fname.c_str());
for ( vector<Ptr<DiagramBase>::ptr>::const_iterator d = diagrams().begin();
d != diagrams().end(); ++d ) {
DiagramDrawer::drawDiag(out,dynamic_cast<const Tree2toNDiagram&>(**d));
out << "\n";
}
}
}
}
StdXCombPtr MatchboxMEBase::makeXComb(Energy newMaxEnergy, const cPDPair & inc,
tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
tPExtrPtr newExtractor, tCascHdlPtr newCKKW,
const PBPair & newPartonBins, tCutsPtr newCuts,
const DiagramVector & newDiagrams, bool mir,
const PartonPairVec&,
tStdXCombPtr newHead,
tMEPtr newME) {
if ( !newME )
newME = this;
Ptr<MatchboxXComb>::ptr xc =
new_ptr(MatchboxXComb(newMaxEnergy, inc,
newEventHandler, newSubProcessHandler,
newExtractor, newCKKW,
newPartonBins, newCuts, newME,
newDiagrams, mir,
newHead));
prepareXComb(*xc);
return xc;
}
StdXCombPtr MatchboxMEBase::makeXComb(tStdXCombPtr newHead,
const PBPair & newPartonBins,
const DiagramVector & newDiagrams,
tMEPtr newME) {
if ( !newME )
newME = this;
Ptr<MatchboxXComb>::ptr xc =
new_ptr(MatchboxXComb(newHead, newPartonBins, newME, newDiagrams));
prepareXComb(*xc);
return xc;
}
void MatchboxMEBase::persistentOutput(PersistentOStream & os) const {
os << theLastXComb << thePhasespace
<< theAmplitude << theScaleChoice << theVirtuals
<< theReweights << theSubprocess << theOneLoop
<< theOneLoopNoBorn << theOneLoopNoLoops
<< epsilonSquarePoleHistograms << epsilonPoleHistograms
<< theMerger
<< theOLPProcess << theNoCorrelations
<< theHavePDFs << checkedPDFs;
}
void MatchboxMEBase::persistentInput(PersistentIStream & is, int) {
is >> theLastXComb >> thePhasespace
>> theAmplitude >> theScaleChoice >> theVirtuals
>> theReweights >> theSubprocess >> theOneLoop
>> theOneLoopNoBorn >> theOneLoopNoLoops
>> epsilonSquarePoleHistograms >> epsilonPoleHistograms
>> theMerger
>> theOLPProcess >> theNoCorrelations
>> theHavePDFs >> checkedPDFs;
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 (auto const & rw : theReweights)
rw->init();
for (auto const & v : virtuals() )
v->init();
}
void MatchboxMEBase::doinitrun() {
MEBase::doinitrun();
if ( matchboxAmplitude() )
matchboxAmplitude()->initrun();
if ( phasespace() )
phasespace()->initrun();
if ( scaleChoice() )
scaleChoice()->initrun();
for (auto const & rw : theReweights)
rw->initrun();
for (auto const & v : virtuals() )
v->initrun();
}
void MatchboxMEBase::dofinish() {
MEBase::dofinish();
for (auto const & b : epsilonSquarePoleHistograms ) {
b.second.dump(factory()->poleData(),"epsilonSquarePoles-",b.first);
}
for (auto const & b : epsilonPoleHistograms ) {
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,1211 +1,1203 @@
// -*- C++ -*-
//
// MatchboxMEBase.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
/** @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<long> getNLightJetVec() const;
/**
* Return the vector that contains the PDG ids of
* the heavy flavours, which are contained in the
* jet particle group.
*/
virtual vector<long> getNHeavyJetVec() const;
/**
* Return the vector that contains the PDG ids of
* the light flavours, which are contained in the
* proton particle group.
*/
virtual vector<long> 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(); }
/**
* leg size
*/
int legsize() const {return int(meMomenta().size());}
//@}
/** @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;
/**
* Get the factorization scale factor
*/
virtual double facFac() const{return factorizationScaleFactor();}
/**
* Return the (QCD) renormalization scale for the last generated phasespace point.
*/
virtual Energy2 renormalizationScale() const;
/**
* Get the renormalization scale factor
*/
virtual double renormalizationScaleFactor() const;
/**
* Get the renormalization scale factor
*/
virtual double renFac() const{return renormalizationScaleFactor();}
/**
* 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;
/**
* Same prefactor for all dSigHat
**/
CrossSection prefactor()const;
/**
* Born part of the cross section
**/
CrossSection dSigHatDRB() const ;
/**
* Virtual corrections of the cross section
**/
CrossSection dSigHatDRV() const ;
/**
* Insertion operators of the cross section
**/
CrossSection dSigHatDRI() const ;
/**
* If diffAlpha is not 1 and the matrix element has insertion operators
* this routine adds the difference between the insertion operator calculated
* with an alpha-Parameter to the insertion operator without alpha-parameter.
*/
CrossSection dSigHatDRAlphaDiff(double alpha) 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; }
/**
* Instruct this matrix element not to include one-loop corrections
*/
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;
/**
* 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 MergerBasePtr merger() const;
/**
* Return the theMerger.
*/
MergerBasePtr merger() ;
/**
* Set the theMerger.
*/
void merger(MergerBasePtr v);
//@}
/** @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 = "",bool slim = false );
/**
* 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 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;
/**
* The merging helper to be used.
* Only the head ME has a pointer to this helper.
*/
MergerBasePtr theMerger;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxMEBase & operator=(const MatchboxMEBase &) = delete;
};
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/Base/MatchboxOLPME.cc b/MatrixElement/Matchbox/Base/MatchboxOLPME.cc
--- a/MatrixElement/Matchbox/Base/MatchboxOLPME.cc
+++ b/MatrixElement/Matchbox/Base/MatchboxOLPME.cc
@@ -1,355 +1,353 @@
// -*- C++ -*-
//
// MatchboxOLPME.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MatchboxOLPME class.
//
#include "MatchboxOLPME.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "MatchboxMEBase.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxOLPME::MatchboxOLPME()
: theOrderInGs(0), theOrderInGem(0), theSetMuToMuR(false),
theUseRunningAlphaS(false), theUseRunningAlphaEW(false) {}
-MatchboxOLPME::~MatchboxOLPME() {}
-
bool MatchboxOLPME::canHandle(const PDVector& p,
Ptr<MatchboxFactory>::tptr factory,
bool) const {
if ( factory->processData()->diagramMap().find(p) !=
factory->processData()->diagramMap().end() )
return true;
vector<Ptr<Tree2toNDiagram>::ptr> diags =
factory->diagramGenerator()->generate(p,orderInGs(),orderInGem());
if ( diags.empty() )
return false;
factory->processData()->diagramMap()[p] = diags;
return true;
}
void MatchboxOLPME::setXComb(tStdXCombPtr xc) {
theLastXComb = xc;
lastMatchboxXComb(xc);
}
double MatchboxOLPME::me2() const {
if ( !calculateTreeME2() )
return lastTreeME2();
evalSubProcess();
return lastTreeME2();
}
double MatchboxOLPME::colourCorrelatedME2(pair<int,int> ij) const {
double cfac = 1.;
double Nc = generator()->standardModel()->Nc();
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
if ( !calculateColourCorrelator(ij) )
return lastColourCorrelator(ij)/cfac;
evalColourCorrelator(ij);
return lastColourCorrelator(ij)/cfac;
}
double MatchboxOLPME::spinColourCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
Lorentz5Momentum p = meMomenta()[ij.first];
Lorentz5Momentum n = meMomenta()[ij.second];
LorentzVector<Complex> polarization = plusPolarization(p,n,ij.first);
Complex pFactor = (polarization*c.momentum())/sqrt(abs(c.scale()));
double avg =
colourCorrelatedME2(ij)*(-c.diagonal()+ (c.scale() > ZERO ? 1. : -1.)*norm(pFactor));
Complex csCorr = 0.0;
if ( calculateColourSpinCorrelator(ij) )
evalSpinColourCorrelator(ij);
csCorr = lastColourSpinCorrelator(ij);
double corr =
2.*real(csCorr*sqr(pFactor));
double Nc = generator()->standardModel()->Nc();
double cfac = 1.;
if ( mePartonData()[ij.first]->iColour() == PDT::Colour8 ) {
cfac = Nc;
} else if ( mePartonData()[ij.first]->iColour() == PDT::Colour3 ||
mePartonData()[ij.first]->iColour() == PDT::Colour3bar ) {
cfac = (sqr(Nc)-1.)/(2.*Nc);
} else assert(false);
return
avg + (c.scale() > ZERO ? 1. : -1.)*corr/cfac;
}
double MatchboxOLPME::spinCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const {
Lorentz5Momentum p = meMomenta()[ij.first];
Lorentz5Momentum n = meMomenta()[ij.second];
LorentzVector<Complex> polarization = plusPolarization(p,n,ij.first);
Complex pFactor = (polarization*c.momentum())/sqrt(abs(c.scale()));
double avg =
me2()*(-c.diagonal()+ (c.scale() > ZERO ? 1. : -1.)*norm(pFactor));
Complex csCorr = 0.0;
if ( calculateSpinCorrelator(ij) )
evalSpinCorrelator(ij);
csCorr = lastSpinCorrelator(ij);
double corr =
2.*real(csCorr*sqr(pFactor));
return
avg + (c.scale() > ZERO ? 1. : -1.)*corr;
}
void MatchboxOLPME::evalSpinCorrelator(pair<int,int>) const {
throw Exception()
<< "MatchboxOLPME::spinCorrelatedME2() is not implemented.\n"
<< "Please check your setup." << Exception::runerror;
}
double MatchboxOLPME::oneLoopDoublePole() const {
if ( !calculateOneLoopPoles() )
return lastOneLoopPoles().first;
evalSubProcess();
return lastOneLoopPoles().first;
}
double MatchboxOLPME::oneLoopSinglePole() const {
if ( !calculateOneLoopPoles() )
return lastOneLoopPoles().second;
evalSubProcess();
return lastOneLoopPoles().second;
}
double MatchboxOLPME::oneLoopInterference() const {
if ( !calculateOneLoopInterference() )
return lastOneLoopInterference();
evalSubProcess();
return lastOneLoopInterference();
}
double MatchboxOLPME::largeNColourCorrelatedME2(pair<int,int> ij,
Ptr<ColourBasis>::tptr basis) const {
if ( trivialColourLegs() )
return MatchboxAmplitude::largeNColourCorrelatedME2(ij,basis);
throw Exception() << "MatchboxOLPME::largeNColourCorrelatedME2(): not supported"
<< Exception::runerror;
return 0.;
}
double MatchboxOLPME::largeNME2(Ptr<ColourBasis>::tptr basis) const {
if ( trivialColourLegs() )
return MatchboxAmplitude::largeNME2(basis);
throw Exception() << "MatchboxOLPME::largeNME2(): not supported"
<< Exception::runerror;
return 0.;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxOLPME::doinit() {
if ( theUseRunningAlphaS && !theSetMuToMuR ) {
throw Exception() << "MatchboxOLPME::doinit(): "
<< "Amplitude '" << name() << "' "
<< "uses a running alpha_s but fixed renormalization scale!\n"
<< Exception::runerror;
}
if ( !theUseRunningAlphaS && theSetMuToMuR ) {
throw Exception() << "MatchboxOLPME::doinit(): "
<< "Amplitude '" << name() << "' "
<< "uses a fixed alpha_s but running renormalization scale!\n"
<< Exception::runerror;
}
if ( !didStartOLP() ) {
string contractFileName =
optionalContractFile().empty() ?
factory()->buildStorage() + name() + ".OLPContract.lh" :
optionalContractFile();
int status = -1;
startOLP(contractFileName,status);
didStartOLP()=true;
if ( status != 1 ) {
throw Exception() << "MatchboxOLPME::doinit(): "
<< "Failed to restart one loop provider for amplitude '"
<< name() << "'\n" << Exception::runerror;
}
}
MatchboxAmplitude::doinit();
}
void MatchboxOLPME::doinitrun() {
if ( theUseRunningAlphaS && !theSetMuToMuR ) {
throw Exception() << "MatchboxOLPME::doinitrun(): "
<< "Amplitude '" << name() << "' "
<< "uses a running alpha_s but fixed renormalization scale!\n"
<< Exception::runerror;
}
if ( !theUseRunningAlphaS && theSetMuToMuR ) {
throw Exception() << "MatchboxOLPME::doinitrun(): "
<< "Amplitude '" << name() << "' "
<< "uses a fixed alpha_s but running renormalization scale!\n"
<< Exception::runerror;
}
if ( !didStartOLP() ) {
string contractFileName =
optionalContractFile().empty() ?
factory()->buildStorage() + name() + ".OLPContract.lh" :
optionalContractFile();
int status = -1;
startOLP(contractFileName,status);
didStartOLP()=true;
if ( status != 1 ) {
throw Exception() << "MatchboxOLPME::doinitrun(): "
<< "Failed to restart one loop provider for amplitude '"
<< name() << "'\n" << Exception::runerror;
}
}
MatchboxAmplitude::doinitrun();
}
Energy2 MatchboxOLPME::mu2() const {
if (theSetMuToMuR) {
return lastMatchboxXComb()->lastRenormalizationScale();
}
return lastSHat();
}
bool MatchboxOLPME::hasRunningAlphaS() const {
if (theUseRunningAlphaS) {
return true;
}
return false;
}
bool MatchboxOLPME::hasRunningAlphaEW() const {
if (theUseRunningAlphaEW) {
return true;
}
return false;
}
void MatchboxOLPME::persistentOutput(PersistentOStream & os) const {
os << theOrderInGs << theOrderInGem << theSetMuToMuR << theUseRunningAlphaS << theUseRunningAlphaEW;
}
void MatchboxOLPME::persistentInput(PersistentIStream & is, int) {
is >> theOrderInGs >> theOrderInGem >> theSetMuToMuR >> theUseRunningAlphaS >> theUseRunningAlphaEW;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeAbstractClass<MatchboxOLPME,MatchboxAmplitude>
describeHerwigMatchboxOLPME("Herwig::MatchboxOLPME", "Herwig.so");
void MatchboxOLPME::Init() {
static ClassDocumentation<MatchboxOLPME> documentation
("MatchboxOLPME implements OLP interfaces.");
static Switch<MatchboxOLPME,bool> interfaceSetMuToMuR
("SetMuToMuR",
"Switch On to set the value of the dimensional regularization parameter mu2 for this OLP"
"to the value of the renormalization scale muR2. Default is Off. The restoration for the "
"full renormalization scale dependence in the DipoleIOperator isn't needed in this case.",
&MatchboxOLPME::theSetMuToMuR, false, false, false);
static SwitchOption interfaceSetMuToMuRYes
(interfaceSetMuToMuR,
"Yes",
"Yes",
true);
static SwitchOption interfaceSetMuToMuRNo
(interfaceSetMuToMuR,
"No",
"No",
false);
interfaceSetMuToMuR.rank(-1);
static Switch<MatchboxOLPME,bool> interfaceUseRunningAlphaS
("UseRunningAlphaS",
"Switch On to set the value of alpha_s for this OLP to the value of the running alpha_s "
"instead of to the value of the reference alpha_s. Default is Off. This also sets the value "
"for hasRunningAlphaS() to true.",
&MatchboxOLPME::theUseRunningAlphaS, false, false, false);
static SwitchOption interfaceUseRunningAlphaSYes
(interfaceUseRunningAlphaS,
"Yes",
"Yes",
true);
static SwitchOption interfaceUseRunningAlphaSNo
(interfaceUseRunningAlphaS,
"No",
"No",
false);
interfaceUseRunningAlphaS.rank(-1);
static Switch<MatchboxOLPME,bool> interfaceUseRunningAlphaEW
("UseRunningAlphaEW",
"Switch On to set the value of alpha_ew for this OLP to the value of the running alpha_ew "
"instead of to the value of the reference alpha_ew. Default is Off. This also sets the value "
"for hasRunningAlphaEW() to true.",
&MatchboxOLPME::theUseRunningAlphaEW, false, false, false);
static SwitchOption interfaceUseRunningAlphaEWYes
(interfaceUseRunningAlphaEW,
"Yes",
"Yes",
true);
static SwitchOption interfaceUseRunningAlphaEWNo
(interfaceUseRunningAlphaEW,
"No",
"No",
false);
interfaceUseRunningAlphaEW.rank(-1);
}
diff --git a/MatrixElement/Matchbox/Base/MatchboxOLPME.h b/MatrixElement/Matchbox/Base/MatchboxOLPME.h
--- a/MatrixElement/Matchbox/Base/MatchboxOLPME.h
+++ b/MatrixElement/Matchbox/Base/MatchboxOLPME.h
@@ -1,332 +1,324 @@
// -*- C++ -*-
//
// MatchboxOLPME.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxOLPME_H
#define Herwig_MatchboxOLPME_H
//
// This is the declaration of the MatchboxOLPME class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxOLPME implements OLP interfaces.
*/
class MatchboxOLPME: public MatchboxAmplitude {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxOLPME();
- /**
- * The destructor.
- */
- virtual ~MatchboxOLPME();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector& p,
Ptr<MatchboxFactory>::tptr,
bool) const;
/**
* Set the (tree-level) order in \f$g_S\f$ in which this matrix
* element should be evaluated.
*/
virtual void orderInGs(unsigned int ogs) { theOrderInGs = ogs; }
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return theOrderInGs; }
/**
* Set the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element should be evaluated.
*/
virtual void orderInGem(unsigned int oge) { theOrderInGem = oge; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return theOrderInGem; }
/**
* Return true, if this amplitude is handled by a BLHA one-loop provider
*/
virtual bool isOLPTree() const { return true; }
/**
* Return true, if this amplitude is handled by a BLHA one-loop provider
*/
virtual bool isOLPLoop() const { return true; }
/**
* Return true, if the colour basis is capable of assigning colour
* flows.
*/
virtual bool haveColourFlows() const { return false; }
/**
* Set the xcomb object.
*/
virtual void setXComb(tStdXCombPtr xc);
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr) {}
/**
* Return the matrix element squared.
*/
virtual double me2() const;
/**
* Return the colour correlated matrix element.
*/
virtual double colourCorrelatedME2(pair<int,int> ij) const;
/**
* Return the large-N colour correlated matrix element.
*/
virtual double largeNColourCorrelatedME2(pair<int,int>,
Ptr<ColourBasis>::tptr) const;
/**
* Return the largeN matrix element squared.
*/
virtual double largeNME2(Ptr<ColourBasis>::tptr largeNBasis) const;
/**
* Return the colour and spin correlated matrix element.
*/
virtual double spinColourCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const;
/**
* Return the spin correlated matrix element.
*/
virtual double spinCorrelatedME2(pair<int,int> ij,
const SpinCorrelationTensor& c) const;
/**
* Return true, if tree-level contributions will be evaluated at amplitude level.
*/
virtual bool treeAmplitudes() const { return false; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return true; }
/**
* Return true, if this amplitude only provides
* one-loop (QCD) corrections.
*/
virtual bool onlyOneLoop() const { return false; }
/**
* Return true, if one-loop contributions will be evaluated at amplitude level.
*/
virtual bool oneLoopAmplitudes() const { return false; }
/**
* Return true, if one loop corrections are given in the conventions
* of everything expanded.
*/
virtual bool isExpanded() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const;
/**
* Indicate that this amplitude is running alphas by itself.
*/
virtual bool hasRunningAlphaS() const;
/**
* Indicate that this amplitude is running alphaew by itself.
*/
virtual bool hasRunningAlphaEW() 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;
/**
* Calculate the one-loop amplitudes for the phasespace point
* stored in lastXComb, if provided.
*/
virtual void prepareOneLoopAmplitudes(Ptr<MatchboxMEBase>::tcptr) {}
/**
* Return the one-loop/tree interference.
*/
virtual double oneLoopInterference() const;
public:
/**
* Call OLP_EvalSubProcess and fill in the results
*/
virtual void evalSubProcess() const = 0;
/**
* Fill in results for the given colour correlator
*/
virtual void evalColourCorrelator(pair<int,int> ij) const = 0;
/**
* Fill in results for the given colour/spin correlator
*/
virtual void evalSpinColourCorrelator(pair<int,int> ij) const = 0;
/**
* Fill in results for the given spin correlator; may not be supported
*/
virtual void evalSpinCorrelator(pair<int,int> ij) 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();
// 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();
//@}
/**
* Set an optional contract file name to be used
*/
static string& optionalContractFile() {
static string s = "";
return s;
}
/**
* Indicate that the OLP has been started
*/
static bool& didStartOLP() {
static bool f = false;
return f;
}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxOLPME & operator=(const MatchboxOLPME &) = delete;
/**
* The (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
unsigned int theOrderInGs;
/**
* The (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
unsigned int theOrderInGem;
/**
* Set the value of the dimensional regularization parameter
* to the value of the renormalization scale
*/
bool theSetMuToMuR;
/**
* Use the running alpha_s instead of the reference alpha_s.
* This also sets hasRunningAlphaS() to true.
*/
bool theUseRunningAlphaS;
/**
* Use the running alpha_ew instead of the reference alpha_ew.
* This also sets hasRunningAlphaEW() to true.
*/
bool theUseRunningAlphaEW;
};
}
#endif /* Herwig_MatchboxOLPME_H */
diff --git a/MatrixElement/Matchbox/Base/MatchboxReweightBase.cc b/MatrixElement/Matchbox/Base/MatchboxReweightBase.cc
--- a/MatrixElement/Matchbox/Base/MatchboxReweightBase.cc
+++ b/MatrixElement/Matchbox/Base/MatchboxReweightBase.cc
@@ -1,45 +1,38 @@
// -*- C++ -*-
//
// MatchboxReweightBase.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxReweightBase class.
//
#include "MatchboxReweightBase.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-MatchboxReweightBase::MatchboxReweightBase() {}
-
-MatchboxReweightBase::~MatchboxReweightBase() {}
-
void MatchboxReweightBase::cloneDependencies(const std::string&) {}
void MatchboxReweightBase::persistentOutput(PersistentOStream &) const {}
void MatchboxReweightBase::persistentInput(PersistentIStream &, int) {}
void MatchboxReweightBase::Init() {
static ClassDocumentation<MatchboxReweightBase> documentation
("MatchboxReweightBase");
}
-// *** 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).
+// The following static variable is needed for the type
+// description system in ThePEG.
DescribeAbstractClass<MatchboxReweightBase,HandlerBase>
describeMatchboxReweightBase("Herwig::MatchboxReweightBase", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Base/MatchboxReweightBase.h b/MatrixElement/Matchbox/Base/MatchboxReweightBase.h
--- a/MatrixElement/Matchbox/Base/MatchboxReweightBase.h
+++ b/MatrixElement/Matchbox/Base/MatchboxReweightBase.h
@@ -1,146 +1,131 @@
// -*- C++ -*-
//
// MatchboxReweightBase.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MatchboxReweightBase_H
#define HERWIG_MatchboxReweightBase_H
//
// This is the declaration of the MatchboxReweightBase class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Handlers/StandardXComb.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxReweightBase is the base class
* for reweighting MatchboxMEBase matrix elements
* as |M|^2 ( w_1 + ... + w_n )
*
*/
class MatchboxReweightBase: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- MatchboxReweightBase();
-
- /**
- * The destructor.
- */
- virtual ~MatchboxReweightBase();
- //@}
-
-public:
-
/**
* Clone this reweight.
*/
Ptr<MatchboxReweightBase>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<MatchboxReweightBase>::ptr>(clone());
}
/**
* Clone the dependencies, using a given prefix.
*/
virtual void cloneDependencies(const std::string& prefix = "");
/**
* Set the XComb object.
*/
virtual void setXComb(tStdXCombPtr) = 0;
/**
* Return true, if applies to the process in the xcomb.
*/
virtual bool apply() const = 0;
/**
* Inform this matrix element that a new phase space
* point is about to be generated, so all caches should
* be flushed.
*/
virtual void flushCaches() = 0;
/**
* Evaluate the reweight.
*/
virtual double evaluate() const = 0;
/**
* Set veto scales on the particles at the given
* SubProcess which has been generated using this
* matrix element.
*/
virtual void setVetoScales(tSubProPtr) const {}
public:
/**
* Dump the setup to an ostream
*/
virtual void print(ostream&) const {}
/**
* Print debug information on the last event
*/
virtual void printLastEvent(ostream&) 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();
// 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.
*/
MatchboxReweightBase & operator=(const MatchboxReweightBase &) = delete;
};
}
#endif /* HERWIG_MatchboxReweightBase_H */
diff --git a/MatrixElement/Matchbox/Base/MergerBase.cc b/MatrixElement/Matchbox/Base/MergerBase.cc
--- a/MatrixElement/Matchbox/Base/MergerBase.cc
+++ b/MatrixElement/Matchbox/Base/MergerBase.cc
@@ -1,44 +1,39 @@
// -*- C++ -*-
//
// MergerBase.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MergerBase class.
//
#include "MergerBase.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MergerBase::MergerBase()
: HandlerBase() {}
-MergerBase::~MergerBase() {}
-
void MergerBase::Init() {
static ClassDocumentation<MergerBase> documentation
("MergerBase is the base class for merging helpers.");
}
-// *** 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).
+// The following static variable is needed for the type
+// description system in ThePEG.
DescribeAbstractNoPIOClass<MergerBase,HandlerBase>
describeHerwigMergerBase("Herwig::MergerBase", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Base/MergerBase.h b/MatrixElement/Matchbox/Base/MergerBase.h
--- a/MatrixElement/Matchbox/Base/MergerBase.h
+++ b/MatrixElement/Matchbox/Base/MergerBase.h
@@ -1,100 +1,94 @@
// -*- C++ -*-
//
// MergerBase.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MergerBase_H
#define HERWIG_MergerBase_H
//
// This is the declaration of the MergerBase class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/MatrixElement/MEBase.h"
#include "Herwig/MatrixElement/Matchbox/Utility/LastMatchboxXCombInfo.h"
#include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXComb.h"
#include "MatchboxMEBase.fh"
namespace Herwig {
using namespace ThePEG;
class MergerBase;
ThePEG_DECLARE_POINTERS(MergerBase,MergerBasePtr);
/**
* \ingroup Matchbox
* \author Johannes Bellm
*
* \brief MergerBase is the base class MergingHelpers.
*
* @see \ref MergerBaseInterfaces "The interfaces"
* defined for MergerBase.
*/
class MergerBase: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MergerBase();
- /**
- * The destructor.
- */
- virtual ~MergerBase();
/// define the ME region for a particle vector.
virtual bool matrixElementRegion(PVector incoming,
PVector outcoming,
Energy winnerScale,
Energy cutscale) const = 0;
/// cross section of as given by the merging
virtual CrossSection MergingDSigDR() = 0;
/// set the current xcomb, called from ME
virtual void setXComb( tStdXCombPtr) = 0;
/// set the current ME
virtual void setME(Ptr<MatchboxMEBase>::ptr) = 0;
/// set kinematics, called from ME
virtual void setKinematics() = 0;
/// clear kinematics, called from ME
virtual void clearKinematics() = 0;
/// generate kinematics, called from ME
virtual bool generateKinematics( const double * ) = 0;
/**
* flush all chaches of the subleading nodes.
* Note: this is called not from the ME but before the first
* kinematics is generated.
**/
virtual void flushCaches() = 0;
/// return the current maximum legs, the shower should veto
virtual size_t maxLegs() const = 0;
/// return the current merging scale,
virtual Energy mergingScale() const = 0;
//@}
public:
/**
* 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();
};
}
#endif /* HERWIG_MergerBase_H */
diff --git a/MatrixElement/Matchbox/Base/SubtractedME.cc b/MatrixElement/Matchbox/Base/SubtractedME.cc
--- a/MatrixElement/Matchbox/Base/SubtractedME.cc
+++ b/MatrixElement/Matchbox/Base/SubtractedME.cc
@@ -1,790 +1,788 @@
// -*- C++ -*-
//
// SubtractedME.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the SubtractedME class.
//
#include "SubtractedME.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/Repository.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Handlers/StdXCombGroup.h"
#include "ThePEG/Utilities/Rebinder.h"
#include "ThePEG/Utilities/Throw.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXCombGroup.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
using namespace Herwig;
SubtractedME::SubtractedME()
: MEGroup(),
theRealShowerSubtraction(false), theVirtualShowerSubtraction(false),
theLoopSimSubtraction(false) {}
-SubtractedME::~SubtractedME() {}
-
Ptr<MatchboxFactory>::tcptr SubtractedME::factory() const {
return MatchboxFactory::currentFactory();
}
bool SubtractedME::subProcessGroups() const {
return
(factory()->subProcessGroups() && !showerApproximation()) ||
factory()->subtractionData() != "";
}
Ptr<ShowerApproximation>::tptr SubtractedME::showerApproximation() const { return factory()->showerApproximation(); }
const vector<Ptr<MatchboxMEBase>::ptr>& SubtractedME::borns() const {
return theBorns.empty() ? factory()->bornMEs() : theBorns;
}
bool SubtractedME::verbose() const { return factory()->verbose(); }
bool SubtractedME::initVerbose() const { return factory()->initVerbose(); }
IBPtr SubtractedME::clone() const {
return new_ptr(*this);
}
IBPtr SubtractedME::fullclone() const {
return new_ptr(*this);
}
StdXCombPtr SubtractedME::makeXComb(Energy newMaxEnergy, const cPDPair & inc,
tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
tPExtrPtr newExtractor, tCascHdlPtr newCKKW,
const PBPair & newPartonBins, tCutsPtr newCuts,
const DiagramVector & newDiagrams, bool mir,
const PartonPairVec& allPBins,
tStdXCombPtr newHead,
tMEPtr newME) {
tMEGroupPtr newMEGroup = dynamic_ptr_cast<tMEGroupPtr>(newME);
if ( !newMEGroup )
newMEGroup = this;
Ptr<MatchboxXCombGroup>::ptr res =
new_ptr(MatchboxXCombGroup(newMaxEnergy, inc,
newEventHandler, newSubProcessHandler,
newExtractor, newCKKW,
newPartonBins, newCuts, newMEGroup,
newDiagrams, mir,
newHead));
res->build(allPBins);
theReal->prepareXComb(*res);
if ( factory()->subtractionData() != "" ) {
set<cPDVector> procs;
for ( DiagramVector::const_iterator d = head()->diagrams().begin();
d != head()->diagrams().end(); ++d ) {
if ( procs.find((**d).partons()) == procs.end() )
procs.insert((**d).partons());
}
for ( set<cPDVector>::const_iterator p = procs.begin();
p != procs.end(); ++p ) {
for ( size_t i = 0; i < (*p).size(); ++i ) {
if ( !(*p)[i]->coloured() )
continue;
if ( i > 1 &&
(*p)[i]->id() == ParticleID::g ) {
softHistograms[SoftSubtractionIndex(*p,i)] = SubtractionHistogram(0.00001,1000.);
ostringstream fname("");
fname << factory()->subtractionData();
const cPDVector& myproc = SoftSubtractionIndex(*p,i).first;
for (cPDVector::const_iterator pp = myproc.begin(); pp != myproc.end(); ++pp) fname << (**pp).PDGName();
fname << "-" << i << "-" << i << "-scatter.dat";
fnamesSoftSubtraction[SoftSubtractionIndex(*p,i)] = fname.str();
if ( theReal->phasespace() )
res->singularLimits().insert(make_pair(i,i));
}
for ( size_t j = i+1; j < (*p).size(); ++j ) {
if ( !(*p)[j]->coloured() )
continue;
long iid = (*p)[i]->id();
long jid = (*p)[j]->id();
if ( i < 2 && j < 2 )
continue;
if ( i < 2 && j > 1 ) {
if ( abs(iid) < 7 && abs(jid) < 7 && iid != jid )
continue;
}
if ( i > 1 && j > 1 ) {
if ( abs(iid) < 7 && abs(jid) < 7 && iid + jid != 0 )
continue;
}
bool haveDipole = false;
for ( MEVector::const_iterator k = dependent().begin();
k != dependent().end(); ++k ) {
const SubtractionDipole& dip = dynamic_cast<const SubtractionDipole&>(**k);
if ( ( (size_t)(dip.realEmitter()) == i && (size_t)(dip.realEmission()) == j ) ||
( (size_t)(dip.realEmitter()) == j && (size_t)(dip.realEmission()) == i ) ) {
haveDipole = true;
break;
}
}
if ( !haveDipole )
continue;
collinearHistograms[CollinearSubtractionIndex(*p,make_pair(i,j))] = SubtractionHistogram(0.00001,1000.);
ostringstream fname("");
fname << factory()->subtractionData();
const cPDVector& myproc = CollinearSubtractionIndex(*p,make_pair(i,j)).first;
for (cPDVector::const_iterator pp = myproc.begin(); pp != myproc.end(); ++pp) fname << (**pp).PDGName();
fname << "-" << i << "-" << j << "-scatter.dat";
fnamesCollinearSubtraction[CollinearSubtractionIndex(*p,make_pair(i,j))] = fname.str();
if ( theReal->phasespace() )
res->singularLimits().insert(make_pair(i,j));
}
}
}
}
return res;
}
void SubtractedME::setXComb(tStdXCombPtr xc) {
MEGroup::setXComb(xc);
lastMatchboxXComb(xc);
}
MEBase::DiagramVector SubtractedME::dependentDiagrams(const cPDVector& proc,
tMEPtr depME) const {
Ptr<SubtractionDipole>::tptr dipole =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(depME);
if ( !dipole ) {
throw Exception() << "SubtractedME: A dependent matrix element of SubtractedME "
<< "has not been derived from SubtractionDipole. "
<< "Please check the corresponding input file." << Exception::runerror;
}
return dipole->underlyingBornDiagrams(proc);
}
vector<Ptr<SubtractionDipole>::ptr> SubtractedME::dipoles() {
if ( dependent().empty() )
getDipoles();
vector<Ptr<SubtractionDipole>::ptr> res;
for ( MEVector::const_iterator k = dependent().begin();
k != dependent().end(); ++k )
res.push_back(dynamic_ptr_cast<Ptr<SubtractionDipole>::ptr>(*k));
return res;
}
void SubtractedME::getDipoles() {
if ( !dependent().empty() )
return;
Ptr<MatchboxMEBase>::tptr real =
dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(head());
if ( borns().empty() || !real )
throw Exception() << "SubtractedME: The SubtractedME '"
<< name() << "' could not generate "
<< "subtraction terms for the real emission "
<< "matrix element '" << real->name() << "'. "
<< "Please check the corresponding input file." << Exception::runerror;
Ptr<MatchboxMEBase>::ptr myRealEmissionME = real->cloneMe();
ostringstream pname;
pname << fullName() << "/" << myRealEmissionME->name();
if ( ! (generator()->preinitRegister(myRealEmissionME,pname.str()) ) )
throw Exception() << "SubtractedME: Matrix element " << pname.str() << " already existing." << Exception::runerror;
myRealEmissionME->cloneDependencies(pname.str());
head(myRealEmissionME);
real = myRealEmissionME;
dependent().clear();
vector<Ptr<SubtractionDipole>::ptr> genDipoles
= real->getDipoles(DipoleRepository::dipoles(factory()->dipoleSet()),borns());
if ( factory()->subtractionData() != "" ) {
for ( vector<Ptr<SubtractionDipole>::ptr>::const_iterator d =
genDipoles.begin(); d != genDipoles.end(); ++d )
(**d).doTestSubtraction();
}
if ( genDipoles.empty() && factory()->initVerbose() ) {
// probably finite real contribution, but warn
generator()->log() << "\nWarning: No subtraction dipoles could be found for the process:\n";
generator()->log() << real->subProcess().legs[0]->PDGName() << " "
<< real->subProcess().legs[1]->PDGName() << " -> ";
for ( PDVector::const_iterator p = real->subProcess().legs.begin() + 2;
p != real->subProcess().legs.end(); ++p )
generator()->log() << (**p).PDGName() << " ";
generator()->log() << "\n" << flush;
generator()->log() << "Assuming finite tree-level O(alphaS) correction.\n";
}
dependent().resize(genDipoles.size());
copy(genDipoles.begin(),genDipoles.end(),dependent().begin());
if ( !factory()->reweighters().empty() ) {
for ( MEVector::const_iterator d = dependent().begin(); d != dependent().end(); ++d ) {
for ( vector<ReweightPtr>::const_iterator rw = factory()->reweighters().begin();
rw != factory()->reweighters().end(); ++rw )
(**d).addReweighter(*rw);
}
}
if ( !factory()->preweighters().empty() ) {
for ( MEVector::const_iterator d = dependent().begin(); d != dependent().end(); ++d ) {
for ( vector<ReweightPtr>::const_iterator rw = factory()->preweighters().begin();
rw != factory()->preweighters().end(); ++rw )
(**d).addPreweighter(*rw);
}
}
}
void SubtractedME::cloneRealME(const string& prefix) {
theReal = dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(head());
if ( theReal ) {
Ptr<MatchboxMEBase>::ptr myRealEmissionME = theReal->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << myRealEmissionME->name();
if ( ! (generator()->preinitRegister(myRealEmissionME,pname.str()) ) )
throw Exception() << "SubtractedME: Matrix element " << pname.str() << " already existing." << Exception::runerror;
myRealEmissionME->cloneDependencies(pname.str());
theReal = myRealEmissionME;
}
head(theReal);
}
void SubtractedME::cloneDipoles(const string& prefix) {
MEVector dipMEs;
for ( MEVector::const_iterator m = dependent().begin();
m != dependent().end(); ++m ) {
Ptr<SubtractionDipole>::tptr dip =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*m);
assert(dip);
Ptr<SubtractionDipole>::ptr cloned = dip->cloneMe();
ostringstream pname;
pname << (prefix == "" ? fullName() : prefix) << "/" << cloned->name();
if ( ! (generator()->preinitRegister(cloned,pname.str()) ) )
throw Exception() << "SubtractedME: Subtraction dipole " << pname.str() << " already existing." << Exception::runerror;
cloned->cloneDependencies(pname.str());
dipMEs.push_back(cloned);
}
dependent() = dipMEs;
}
vector<Ptr<SubtractionDipole>::ptr> SubtractedME::splitDipoles(const cPDVector& born) {
vector<Ptr<SubtractionDipole>::ptr> dips = dipoles();
vector<Ptr<SubtractionDipole>::ptr> res;
for ( vector<Ptr<SubtractionDipole>::ptr>::iterator d = dips.begin();
d != dips.end(); ++d ) {
for ( DiagramVector::const_iterator p = (**d).underlyingBornME()->diagrams().begin();
p != (**d).underlyingBornME()->diagrams().end(); ++p )
if ( born == (**p).partons() ) {
res.push_back(*d);
break;
}
}
return res;
}
void SubtractedME::doRealEmissionScales() {
for ( MEVector::const_iterator m = dependent().begin();
m != dependent().end(); ++m ) {
Ptr<SubtractionDipole>::tptr dip =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*m);
assert(dip);
dip->doRealEmissionScales();
}
}
void SubtractedME::doRealShowerSubtraction() {
theRealShowerSubtraction = true;
for ( MEVector::const_iterator m = dependent().begin();
m != dependent().end(); ++m ) {
Ptr<SubtractionDipole>::tptr dip =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*m);
assert(dip);
dip->showerApproximation(showerApproximation());
dip->doRealShowerSubtraction();
}
}
void SubtractedME::doVirtualShowerSubtraction() {
theVirtualShowerSubtraction = true;
for ( MEVector::const_iterator m = dependent().begin();
m != dependent().end(); ++m ) {
Ptr<SubtractionDipole>::tptr dip =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*m);
assert(dip);
dip->showerApproximation(showerApproximation());
dip->doVirtualShowerSubtraction();
}
}
void SubtractedME::doLoopSimSubtraction() {
theLoopSimSubtraction = true;
for ( MEVector::const_iterator m = dependent().begin();
m != dependent().end(); ++m ) {
Ptr<SubtractionDipole>::tptr dip =
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*m);
assert(dip);
dip->showerApproximation(showerApproximation());
dip->doLoopSimSubtraction();
}
}
void SubtractedME::setVetoScales(tSubProPtr) const {}
void SubtractedME::fillProjectors() {
if ( !virtualShowerSubtraction() && !loopSimSubtraction() )
return;
Ptr<StdXCombGroup>::tptr group =
dynamic_ptr_cast<Ptr<StdXCombGroup>::tptr>(lastXCombPtr());
for ( vector<StdXCombPtr>::const_iterator d = group->dependent().begin();
d != group->dependent().end(); ++d ) {
if ( !(**d).matrixElement()->apply() ||
!(**d).kinematicsGenerated() )
continue;
if ( (**d).willPassCuts() &&
(**d).lastMECrossSection()/picobarn != 0.0 ) {
lastXCombPtr()->projectors().insert(abs((**d).cutWeight()*(**d).lastMECrossSection()/picobarn),*d);//
}
}
}
double SubtractedME::reweightHead(const vector<tStdXCombPtr>&) {
if ( showerApproximation() ) {
if ( realShowerSubtraction() )
return 1.;
if ( virtualShowerSubtraction() || loopSimSubtraction() )
return 0.;
}
return 1.;
}
double SubtractedME::reweightDependent(tStdXCombPtr xc, const vector<tStdXCombPtr>& dep) {
if ( showerApproximation() ) {
if ( realShowerSubtraction() )
return 1.0;
if ( virtualShowerSubtraction() || loopSimSubtraction() ) {
if ( !lastXComb().lastProjector() )
return 0.0;
if ( xc != lastXComb().lastProjector() )
return 0.0;
double invPAlpha = 0.;
for ( vector<tStdXCombPtr>::const_iterator d = dep.begin(); d != dep.end(); ++d ) {
if ( !(**d).matrixElement()->apply() ||
!(**d).kinematicsGenerated() )
continue;
if ( (**d).willPassCuts() &&
(**d).lastMECrossSection()/picobarn != 0.0 ) {
invPAlpha += abs((**d).cutWeight()*(**d).lastMECrossSection()/picobarn);
}
}
assert(invPAlpha != 0.0 && xc->cutWeight() != 0.0 && xc->lastMECrossSection()/picobarn != 0.0);
double palpha = abs((xc->cutWeight())*(xc->lastMECrossSection()/picobarn))/invPAlpha;
return 1./palpha;
}
}
return 1.;
}
void SubtractedME::doinit() {
// has been deactivated by the factory
if ( !head() ) {
MEBase::doinit();
return;
}
theReal = dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(head());
if ( theReal ) {
getDipoles();
}
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator b = theBorns.begin();
b != theBorns.end(); ++b )
(**b).init();
if ( initVerbose() )
print(Repository::clog());
MEGroup::doinit();
}
void SubtractedME::doinitrun() {
// has been deactivated by the factory
if ( !head() ) {
MEBase::doinitrun();
return;
}
theReal = dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(head());
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator b = theBorns.begin();
b != theBorns.end(); ++b )
(**b).initrun();
MEGroup::doinitrun();
}
void SubtractedME::dofinish() {
// has been deactivated by the factory
if ( !head() ) {
MEBase::dofinish();
return;
}
MEGroup::dofinish();
for ( map<CollinearSubtractionIndex,SubtractionHistogram>::
const_iterator b = collinearHistograms.begin();
b != collinearHistograms.end(); ++b ) {
b->second.dump(factory()->subtractionData(),
factory()->subtractionPlotType(),
factory()->subtractionScatterPlot(),
b->first.first,
b->first.second.first,
b->first.second.second);
}
for ( map<SoftSubtractionIndex,SubtractionHistogram>::
const_iterator b = softHistograms.begin();
b != softHistograms.end(); ++b ) {
b->second.dump(factory()->subtractionData(),
factory()->subtractionPlotType(),
factory()->subtractionScatterPlot(),
b->first.first,
b->first.second,
b->first.second);
}
}
void SubtractedME::print(ostream& os) const {
os << "--- SubtractedME setup ---------------------------------------------------------\n";
os << " '" << name() << "' subtracting real emission\n '"
<< head()->name() << "' using the dipoles:\n";
for ( MEVector::const_iterator d = dependent().begin();
d != dependent().end(); ++d )
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*d)->print(os);
os << "--------------------------------------------------------------------------------\n";
os << flush;
}
void SubtractedME::printLastEvent(ostream& os) const {
os << "--- SubtractedME last event information ----------------------------------------\n";
os << " for subtracted matrix element '" << name() << "'\n";
os << " real emission event information:\n";
dynamic_ptr_cast<Ptr<MatchboxMEBase>::tptr>(head())->printLastEvent(os);
os << " dipoles event information:\n";
for ( MEVector::const_iterator d = dependent().begin();
d != dependent().end(); ++d )
dynamic_ptr_cast<Ptr<SubtractionDipole>::tptr>(*d)->printLastEvent(os);
os << "--- end SubtractedME last event information ------------------------------------\n\n\n";
os << flush;
}
void SubtractedME::lastEventStatistics() {
MEGroup::lastEventStatistics();
if ( !generator() )
return;
/*
if ( verbose() )
printLastEvent(generator()->log());
*/
if ( !collinearHistograms.empty() )
lastEventSubtraction();
}
SubtractedME::SubtractionHistogram::
SubtractionHistogram(double low,
double up,
unsigned int nbins)
: lower(low) {
nbins = nbins + 1;
double c = log10(up/low) / (nbins-1.);
for ( unsigned int k = 1; k < nbins; ++k ) {
bins[low*pow(10.0,k*c)] = make_pair(Constants::MaxDouble,0.);
}
}
void SubtractedME::SubtractionHistogram::persistentOutput(PersistentOStream& os) const {
os << lower << bins;
}
void SubtractedME::SubtractionHistogram::persistentInput(PersistentIStream& is) {
is >> lower >> bins;
}
void SubtractedME::SubtractionHistogram::
dump(const std::string& prefix,
const int& plottype,
const bool& scatterplot,
const cPDVector& proc,
int i, int j) const {
bool bbmin = true;
double bmin = bins.begin()->first;
double bmax = bins.begin()->first;
ostringstream fname("");
for ( cPDVector::const_iterator p = proc.begin();
p != proc.end(); ++p )
fname << (**p).PDGName();
fname << "-" << i << "-" << j;
ofstream out((prefix+fname.str()+".dat").c_str());
for ( map<double,pair<double,double> >::const_iterator b = bins.begin();
b != bins.end(); ++b ) {
map<double,pair<double,double> >::const_iterator bp = b;
if (bp== bins.begin())continue;
--bp;
if ( b->second.first != Constants::MaxDouble ||
b->second.second != 0.0 ) {
if ( b != bins.begin() ){
out << bp->first;
if (bbmin){
bmin = bp->first;
bbmin = false;
}
}
else {
out << lower;
if (bbmin){
bmin = lower;
bbmin = false;
}
}
bmax = b->first;
out << " " << b->first
<< " " << b->second.first
<< " " << b->second.second
<< "\n" << flush;
}
}
double xmin = pow(10.0, floor(log10(bmin)));
double xmax = pow(10.0, ceil(log10(bmax)));
ofstream gpout((prefix+fname.str()+".gp").c_str());
gpout << "set terminal epslatex color solid\n"
<< "set output '" << fname.str() << "-plot.tex'\n"
<< "set format x '$10^{%T}$'\n"
<< "set logscale x\n"
<< "set xrange [" << xmin << ":" << xmax << "]\n";
if ( i != j ) {
gpout << "set xlabel '$\\sqrt{s_{" << i << j << "}}/{\\rm GeV}$'\n";
} else {
gpout << "set xlabel '$E_{" << i << "}/{\\rm GeV}$'\n";
}
if (plottype == 1){
gpout << "set size 0.5,0.6\n"
<< "set yrange [0:2]\n";
gpout << "plot 1 w lines lc rgbcolor \"#DDDDDD\" notitle, '" << fname.str()
<< ".dat' u (($1+$2)/2.):3:($4 < 4. ? $4 : 4.) w filledcurves lc rgbcolor \"#00AACC\" t '$";
}
else if (plottype == 2){
gpout << "set key left top Left reverse\n"
<< "set logscale y\n"
<< "set format y '$10^{%T}$'\n"
<< "set size 0.7,0.8\n"
<< "set yrange [1e-6:1e1]\n"
<< "set ylabel '$\\max\\left\\{\\left|\\mathcal{D}-\\mathcal{M}\\right|/\\left|\\mathcal{M}\\right|\\right\\}$'\n"
<< "unset bars\n";
gpout << "plot '";
if (scatterplot) gpout << fname.str() << "-scatter.dat' w points pt 7 ps 0.5 lc rgbcolor \"#00AACC\" not, \\\n'";
gpout << fname.str() << ".dat' u (($1+$2)/2.):4 w lines lw 4 lc rgbcolor \"#00AACC\" t '$";
}
for ( size_t k = 0; k < proc.size(); k++ ) {
if ( k == 2 )
gpout << "\\to ";
gpout << (proc[k]->id() < 0 ? "\\bar{" : "")
<< (proc[k]->id() < 0 ? proc[k]->CC()->PDGName() : proc[k]->PDGName())
<< (proc[k]->id() < 0 ? "}" : "") << " ";
}
gpout << "$'\n";
gpout << "reset\n";
}
void SubtractedME::lastEventSubtraction() {
tStdXCombGroupPtr xc = dynamic_ptr_cast<tStdXCombGroupPtr>(lastXCombPtr());
CrossSection xcme2 = xc->lastHeadCrossSection();
CrossSection xcdip = ZERO;
for ( vector<StdXCombPtr>::const_iterator d = xc->dependent().begin();
d != xc->dependent().end(); ++d ) {
if ( !(*d) )
continue;
if ( !(**d).matrixElement()->apply() )
continue;
if ( !(**d).willPassCuts() )
continue;
xcdip += (**d).lastCrossSection();
}
// want a real emission safely above the cut
if ( xc->cutWeight() < 1.0 )
return;
double delta;
if (factory()->subtractionPlotType() == 2) delta = abs(xcdip+xcme2)/abs(xcme2);
else delta = abs(xcdip)/abs(xcme2);
if ( theReal->phasespace() ) {
size_t i = lastSingularLimit()->first;
size_t j = lastSingularLimit()->second;
if ( i == j &&
softHistograms.find(SoftSubtractionIndex(head()->mePartonData(),i))
!= softHistograms.end() ) {
softHistograms[SoftSubtractionIndex(head()->mePartonData(),i)].
book(meMomenta()[i].t()/GeV,delta);
if ( factory()->subtractionScatterPlot() ){
ofstream outstream((fnamesSoftSubtraction[SoftSubtractionIndex(head()->mePartonData(),i)]).c_str(),ofstream::app);
outstream << meMomenta()[i].t()/GeV << " " << delta << "\n";
}
}
if ( i != j &&
collinearHistograms.find(CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j)))
!= collinearHistograms.end() ) {
double s = sqrt(2.*meMomenta()[i]*meMomenta()[j])/GeV;
collinearHistograms[CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j))].
book(s,delta);
if ( factory()->subtractionScatterPlot() ){
ofstream outstream((fnamesCollinearSubtraction[CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j))]).c_str(),ofstream::app);
outstream << s << " " << delta << "\n";
}
}
return;
}
for ( size_t i = 0; i < meMomenta().size(); ++i ) {
if ( i > 1 ) {
if ( softHistograms.find(SoftSubtractionIndex(head()->mePartonData(),i))
!= softHistograms.end() ) {
softHistograms[SoftSubtractionIndex(head()->mePartonData(),i)].
book(meMomenta()[i].t()/GeV,delta);
if ( factory()->subtractionScatterPlot() ){
ofstream outstream((fnamesSoftSubtraction[SoftSubtractionIndex(head()->mePartonData(),i)]).c_str(),ofstream::app);
outstream << meMomenta()[i].t()/GeV << " " << delta << "\n";
}
}
}
for ( size_t j = i+1; j < meMomenta().size(); ++j ) {
if ( collinearHistograms.find(CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j)))
== collinearHistograms.end() )
continue;
double s = sqrt(2.*meMomenta()[i]*meMomenta()[j])/GeV;
collinearHistograms[CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j))].
book(s,delta);
if ( factory()->subtractionScatterPlot() ){
ofstream outstream((fnamesCollinearSubtraction[CollinearSubtractionIndex(head()->mePartonData(),make_pair(i,j))]).c_str(),ofstream::app);
outstream << s << " " << delta << "\n";
}
}
}
}
void SubtractedME::persistentOutput(PersistentOStream & os) const {
os << theLastXComb << theBorns << theReal
<< collinearHistograms << softHistograms
<< fnamesSoftSubtraction
<< theRealShowerSubtraction << theVirtualShowerSubtraction
<< theLoopSimSubtraction;
}
void SubtractedME::persistentInput(PersistentIStream & is, int) {
is >> theLastXComb >> theBorns >> theReal
>> collinearHistograms >> softHistograms
>> fnamesSoftSubtraction
>> theRealShowerSubtraction >> theVirtualShowerSubtraction
>> theLoopSimSubtraction;
lastMatchboxXComb(theLastXComb);
}
void SubtractedME::Init() {
static ClassDocumentation<SubtractedME> documentation
("SubtractedME represents a subtracted real emission matrix element.");
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<SubtractedME,MEGroup>
describeHerwigSubtractedME("Herwig::SubtractedME", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Base/SubtractedME.h b/MatrixElement/Matchbox/Base/SubtractedME.h
--- a/MatrixElement/Matchbox/Base/SubtractedME.h
+++ b/MatrixElement/Matchbox/Base/SubtractedME.h
@@ -1,536 +1,528 @@
// -*- C++ -*-
//
// SubtractedME.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_SubtractedME_H
#define HERWIG_SubtractedME_H
//
// This is the declaration of the SubtractedME class.
//
#include "ThePEG/MatrixElement/MEGroup.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
#include "Herwig/MatrixElement/Matchbox/Utility/LastMatchboxXCombInfo.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.fh"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief SubtractedME represents a subtracted real emission matrix element.
*
* @see \ref SubtractedMEInterfaces "The interfaces"
* defined for SubtractedME.
*/
class SubtractedME:
public MEGroup,
public LastMatchboxXCombInfo {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
SubtractedME();
- /**
- * The destructor.
- */
- virtual ~SubtractedME();
- //@}
-
public:
/**
* Return the factory which produced this matrix element
*/
Ptr<MatchboxFactory>::tcptr factory() const;
/** @name Phasespace and subprocess information */
//@{
/**
* For the given event generation setup return an 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());
/**
* Set the XComb object to be used in the next call to
* generateKinematics() and dSigHatDR().
*/
virtual void setXComb(tStdXCombPtr);
/**
* Return true, if the same additional random numbers
* should be presented to any of the dependent
* matrix elements.
*/
virtual bool uniformAdditional() const { return true; }
/**
* 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; }
/**
* Given a process from the head matrix element,
* return a list of diagrams which should be considered for
* the given dependent matrix element.
*/
virtual MEBase::DiagramVector dependentDiagrams(const cPDVector& proc,
tMEPtr depME) const;
/**
* Return true, if SubProcessGroups should be
* setup from this MEGroup. If not, a single SubProcess
* is constructed from the data provided by the
* head matrix element.
*/
virtual bool subProcessGroups() const;
/**
* Return true, if one of the dependent subprocesses should be
* constructed in place of the one driven by the head matrix element
* or a full subprocess group.
*/
virtual bool selectDependentSubProcess() const { return false; }
/**
* Fill the projectors object of xcombs to choose subprocesses
* different than the one currently integrated.
*/
virtual void fillProjectors();
/**
* Return true, if projectors will be used
*/
virtual bool willProject() const {
return virtualShowerSubtraction() || loopSimSubtraction();
}
/**
* Return true, if this MEGroup will reweight the contributing cross
* sections.
*/
virtual bool groupReweighted() const {
return showerApproximation();
}
/**
* Reweight the head cross section
*/
virtual double reweightHead(const vector<tStdXCombPtr>&);
/**
* Reweight the dependent cross section
*/
virtual double reweightDependent(tStdXCombPtr, const vector<tStdXCombPtr>&);
/**
* Switch on or off that scales should be calculated from real emission kinematics
*/
void doRealEmissionScales();
//@}
/** @name Methods relevant to matching */
//@{
/**
* Inform this matrix element that a new phase space
* point is about to be generated, so all caches should
* be flushed.
*/
virtual void flushCaches() {
MEGroup::flushCaches();
if ( showerApproximation() )
showerApproximation()->resetBelowCutoff();
}
/**
* Return the shower approximation.
*/
Ptr<ShowerApproximation>::tptr showerApproximation() const;
/**
* Indicate that the shower real emission contribution should be subtracted.
*/
void doRealShowerSubtraction();
/**
* 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();
/**
* 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();
/**
* Return true, if the loopsim matched virtual contribution should be subtracted.
*/
bool loopSimSubtraction() const { return theLoopSimSubtraction; }
/**
* Return true, if this configuration of cross sections should not
* be included due to their relative magnitude. Arguments are head
* cross section and dependent cross section, including all
* reweights.
*/
virtual bool discard(const CrossSection&, const CrossSection&) const { return false; }
//@}
/** @name Matrix element and dipole information */
//@{
/**
* Return the subtraction dipoles.
*/
vector<Ptr<SubtractionDipole>::ptr> dipoles();
/**
* Return the underlying born matrix elements.
*/
const vector<Ptr<MatchboxMEBase>::ptr>& borns() const;
/**
* Access the underlying born matrix elements,
* overriding the ones contained in the factory object.
*/
void setBorns(const vector<Ptr<MatchboxMEBase>::ptr>& newBorns) { theBorns = newBorns; }
/**
* Build up dipoles needed.
*/
void getDipoles();
/**
* Clone all dipoles.
*/
void cloneDipoles(const string& prefix = "");
/**
* Clone the real emission matrix element.
*/
void cloneRealME(const string& prefix = "");
/**
* Clone all dependencies.
*/
void cloneDependencies(const string& prefix = "") {
cloneDipoles(prefix);
cloneRealME(prefix);
}
/**
* Return all dipoles matching the given Born process
*/
vector<Ptr<SubtractionDipole>::ptr> splitDipoles(const cPDVector&);
//@}
/** @name Veto scale settings */
//@{
/**
* Set veto scales on the particles at the given
* SubProcess which has been generated using this
* matrix element.
*/
virtual void setVetoScales(tSubProPtr) const;
//@}
/** @name Diagnostic information */
//@{
/**
* Dump the setup to an ostream
*/
void print(ostream&) const;
/**
* Collect information on the last evaluated phasespace
* point for verification or debugging purposes. This
* only called, if the StdXCombGroup did accumulate
* a non-zero cross section from this ME group.
*/
virtual void lastEventStatistics();
/**
* Print debug information on the last event
*/
void printLastEvent(ostream&) const;
/**
* Check the subtraction for the last event
*/
void lastEventSubtraction();
/**
* Return true, if verbose
*/
bool verbose() const;
/**
* Return true, if verbose
*/
bool initVerbose() const;
//@}
/** @name Setup of Subtracted ME 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; }
/**
* Simple envelope histogram to keep track of subtraction
*/
struct SubtractionHistogram {
/**
* The lower bound
*/
double lower;
/**
* The bins, indexed by upper bound.
*/
map<double,pair<double,double> > bins;
/**
* Constructor
*/
SubtractionHistogram(double low = 0.001,
double up = 10.,
unsigned int nbins = 100);
/**
* Book an event.
*/
void book(double inv, double diff) {
map<double,pair<double,double> >::iterator b =
bins.upper_bound(inv);
if ( b == bins.end() ) return;
b->second.first = min(b->second.first,diff);
b->second.second = max(b->second.second,diff);
}
/**
* Write to file given name and invariant.
*/
void dump(const std::string& prefix,
const int& plottype,
const bool& scatterplot,
const cPDVector& proc,
int i, int j) const;
/**
* Write to persistent ostream
*/
void persistentOutput(PersistentOStream&) const;
/**
* Read from persistent istream
*/
void persistentInput(PersistentIStream&);
};
//@}
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 underlying born matrix elements, overriding the ones
* contained in the factory object.
*/
vector<Ptr<MatchboxMEBase>::ptr> theBorns;
/**
* Pointer to the head real emission ME casted to a MatchboxMEBase
* object.
*/
Ptr<MatchboxMEBase>::ptr theReal;
/**
* Define the key for the collinear subtraction data.
*/
typedef pair<cPDVector,pair<size_t, size_t> > CollinearSubtractionIndex;
/**
* subtraction data for collinear limits.
*/
map<CollinearSubtractionIndex,SubtractionHistogram> collinearHistograms;
/**
* names of files to which subtraction data is written for all phase space points individually
*/
map<CollinearSubtractionIndex,string> fnamesCollinearSubtraction;
/**
* Define the key for the soft subtraction data.
*/
typedef pair<cPDVector,size_t> SoftSubtractionIndex;
/**
* subtraction data for soft limits.
*/
map<SoftSubtractionIndex,SubtractionHistogram> softHistograms;
/**
* names of files to which subtraction data is written for all phase space points individually
*/
map<SoftSubtractionIndex,string> fnamesSoftSubtraction;
/**
* 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;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
SubtractedME & operator=(const SubtractedME &) = delete;
};
inline PersistentOStream& operator<<(PersistentOStream& os,
const SubtractedME::SubtractionHistogram& h) {
h.persistentOutput(os);
return os;
}
inline PersistentIStream& operator>>(PersistentIStream& is,
SubtractedME::SubtractionHistogram& h) {
h.persistentInput(is);
return is;
}
}
#endif /* HERWIG_SubtractedME_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbar.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbar.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbar.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbar.cc
@@ -1,169 +1,167 @@
// -*- C++ -*-
//
// MatchboxAmplitudeggttbar.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudeggttbar class.
//
#include "MatchboxAmplitudeggttbar.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudeggttbar::MatchboxAmplitudeggttbar() {}
-MatchboxAmplitudeggttbar::~MatchboxAmplitudeggttbar() {}
-
IBPtr MatchboxAmplitudeggttbar::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudeggttbar::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudeggttbar::setupParams(map<string, double> &MGParams){
// create parameter map for adapted Madgraph amplitude to use
MGParams["aS"] = SM().alphaS();
MGParams["MZ"] = getParticleData(ParticleID::Z0) -> hardProcessMass()/GeV;
MGParams["MW"] = getParticleData(ParticleID::Wplus) -> hardProcessMass()/GeV;
MGParams["MH"] = getParticleData(ParticleID::h0) -> hardProcessMass()/GeV;
MGParams["WW"] = getParticleData(ParticleID::Wplus) ->hardProcessWidth()/GeV;
MGParams["WZ"] = getParticleData(ParticleID::Z0) ->hardProcessWidth()/GeV;
MGParams["WH"] = getParticleData(ParticleID::h0) ->hardProcessWidth()/GeV;
MGParams["MT"] = getParticleData(ParticleID::t) -> hardProcessMass()/GeV;
MGParams["MB"] = getParticleData(ParticleID::b) -> hardProcessMass()/GeV;
MGParams["WT"] = getParticleData(ParticleID::t) ->hardProcessWidth()/GeV;
MGParams["WB"] = getParticleData(ParticleID::b) ->hardProcessWidth()/GeV;
MGParams["MTA"] = getParticleData(ParticleID::tauminus)-> hardProcessMass()/GeV;
MGParams["GF"] = SM().fermiConstant()*GeV2;
MGParams["aEWM1"] = 1./SM().alphaEMMZ();
return;
}
void MatchboxAmplitudeggttbar::doinit() {
setupParams(MGParams_);
MatchboxAmplitude::doinit();
nPoints(4);
}
void MatchboxAmplitudeggttbar::doinitrun() {
setupParams(MGParams_);
MatchboxAmplitude::doinitrun();
nPoints(4);
}
bool MatchboxAmplitudeggttbar::canHandle(const PDVector& proc) const {
// check process is gg > ttbar
if ( proc.size() != 4 )
return false;
PDVector xproc = proc;
PDVector::iterator top = xproc.begin();
long topId = 0;
for ( ; top != xproc.end(); ++top )
if ( (**top).id() == 6 ) {
break;
}
if ( top == xproc.end() )
return false;
topId = (**top).id();
xproc.erase(top);
PDVector::iterator antiTop = xproc.begin();
for ( ; antiTop != xproc.end(); ++antiTop )
if ( (**antiTop).id() == -topId ) {
break;
}
if ( antiTop == xproc.end() )
return false;
xproc.erase(antiTop);
return (xproc[0]->id()==21 && xproc[1]->id()==21);
}
void MatchboxAmplitudeggttbar::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
momentum(0,amplitudeMomentum(0));
momentum(1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudeggttbar::evaluate(size_t a, const vector<int>& hel, Complex& largeN) {
// set up momenta to pass into Madgraph amplitude
vector<double*> p;
p.push_back(mom0); p.push_back(mom1); p.push_back(mom2); p.push_back(mom3);
for (int ip=0; ip<4; ++ip){
p[ip][0] = abs(momentum(ip).e())<1.e-13 ? 0.0:double(momentum(ip).e()*amplitudeScale()/GeV);
p[ip][1] = abs(momentum(ip).x())<1.e-13 ? 0.0:double(momentum(ip).x()*amplitudeScale()/GeV);
p[ip][2] = abs(momentum(ip).y())<1.e-13 ? 0.0:double(momentum(ip).y()*amplitudeScale()/GeV);
p[ip][3] = abs(momentum(ip).z())<1.e-13 ? 0.0:double(momentum(ip).z()*amplitudeScale()/GeV);
}
// calculate amplitudes
vector<complex<double> > amplitudes;
MG_gg2ttx process;
process.initProc(MGParams_);
process.setMomenta(p);
process.sigmaKin(amplitudes, hel);
complex<double> matrixElement;
complex<double> i = complex<double> (0, 1);
// calculate colour flows
if (a==0) matrixElement = 0.;
else if (a==1) matrixElement = i*amplitudes[0] - amplitudes[1];
else if (a==2) matrixElement =-i*amplitudes[0] - amplitudes[2];
else assert(false);
largeN = matrixElement;
return matrixElement;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudeggttbar::persistentOutput(PersistentOStream &) const {}
void MatchboxAmplitudeggttbar::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudeggttbar,MatchboxAmplitude>
describeHerwigMatchboxAmplitudeggttbar("Herwig::MatchboxAmplitudeggttbar", "HwMatchboxBuiltin.so");
void MatchboxAmplitudeggttbar::Init() {
static ClassDocumentation<MatchboxAmplitudeggttbar> documentation
("MatchboxAmplitudeggttbar");
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbar.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbar.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbar.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbar.h
@@ -1,201 +1,193 @@
// -*- C++ -*-
//
// MatchboxAmplitudeggttbar.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudeggttbar_H
#define Herwig_MatchboxAmplitudeggttbar_H
//
// This is the declaration of the MatchboxAmplitudeggttbar class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
#include "MG_gg2ttx.h"
#include "HelAmps_sm.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Alix Wilcock
*
* \brief MatchboxAmplitudeggttbar
*/
class MatchboxAmplitudeggttbar:
public MatchboxAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudeggttbar();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudeggttbar();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const {return 2; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 0; }
/**
* Return true, if this amplitude will not require colour correlations.
*/
virtual bool noCorrelations() const { return false; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
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();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudeggttbar & operator=(const MatchboxAmplitudeggttbar &) = delete;
/**
* Containers for external particle momenta
*/
double mom0 [4];
double mom1 [4];
double mom2 [4];
double mom3 [4];
/**
* Fill MGParams_ with Herwig values of parameters
*/
void setupParams(map<string, double> & MGParams);
/**
* Stores parameters needed in MG_process
*/
map<string,double> MGParams_;
};
}
#endif /* Herwig_MatchboxAmplitudeggttbar_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbarg.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbarg.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbarg.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbarg.cc
@@ -1,198 +1,196 @@
// -*- C++ -*-
//
// MatchboxAmplitudeggttbarg.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudeggttbarg class.
//
#include "MatchboxAmplitudeggttbarg.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudeggttbarg::MatchboxAmplitudeggttbarg() {}
-MatchboxAmplitudeggttbarg::~MatchboxAmplitudeggttbarg() {}
-
IBPtr MatchboxAmplitudeggttbarg::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudeggttbarg::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudeggttbarg::setupParams(map<string, double> &MGParams){
// create parameter map for adapted Madgraph amplitude to use
MGParams["aS"] = SM().alphaS();
MGParams["MZ"] = getParticleData(ParticleID::Z0) -> hardProcessMass()/GeV;
MGParams["MW"] = getParticleData(ParticleID::Wplus) -> hardProcessMass()/GeV;
MGParams["MH"] = getParticleData(ParticleID::h0) -> hardProcessMass()/GeV;
MGParams["WW"] = getParticleData(ParticleID::Wplus) ->hardProcessWidth()/GeV;
MGParams["WZ"] = getParticleData(ParticleID::Z0) ->hardProcessWidth()/GeV;
MGParams["WH"] = getParticleData(ParticleID::h0) ->hardProcessWidth()/GeV;
MGParams["MT"] = getParticleData(ParticleID::t) -> hardProcessMass()/GeV;
MGParams["MB"] = getParticleData(ParticleID::b) -> hardProcessMass()/GeV;
MGParams["WT"] = getParticleData(ParticleID::t) ->hardProcessWidth()/GeV;
MGParams["WB"] = getParticleData(ParticleID::b) ->hardProcessWidth()/GeV;
MGParams["MTA"] = getParticleData(ParticleID::tauminus)-> hardProcessMass()/GeV;
MGParams["GF"] = SM().fermiConstant()*GeV2;
MGParams["aEWM1"] = 1./SM().alphaEMMZ();
return;
}
void MatchboxAmplitudeggttbarg::doinit() {
setupParams(MGParams_);
MatchboxAmplitude::doinit();
nPoints(5);
}
void MatchboxAmplitudeggttbarg::doinitrun() {
setupParams(MGParams_);
MatchboxAmplitude::doinitrun();
nPoints(5);
}
bool MatchboxAmplitudeggttbarg::canHandle(const PDVector& proc) const {
// check process is gg > ttbarg
if ( proc.size() != 5 )
return false;
PDVector xproc = proc;
PDVector::iterator top = xproc.begin();
long topId = 0;
for ( ; top != xproc.end(); ++top )
if ( (**top).id() == 6 ) {
break;
}
if ( top == xproc.end() )
return false;
topId = (**top).id();
xproc.erase(top);
PDVector::iterator antiTop = xproc.begin();
for ( ; antiTop != xproc.end(); ++antiTop )
if ( (**antiTop).id() == -topId ) {
break;
}
if ( antiTop == xproc.end() )
return false;
xproc.erase(antiTop);
if ( xproc.size() != 3 )
return false;
return (xproc[0]->id() == 21 && xproc[1]->id() == 21 && xproc[2]->id() == 21);
}
void MatchboxAmplitudeggttbarg::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
momentum(0,amplitudeMomentum(0));
momentum(1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
momentum(4,amplitudeMomentum(4));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudeggttbarg::evaluate(size_t a, const vector<int>& hel, Complex& largeN) {
// set up momenta to pass into Madgraph amplitude
vector<double*> p;
p.push_back(mom0); p.push_back(mom1); p.push_back(mom2); p.push_back(mom3); p.push_back(mom4);
for (int ip=0; ip<5; ++ip){
p[ip][0] = abs(momentum(ip).e())<1.e-13 ? 0.0:double(momentum(ip).e()*amplitudeScale()/GeV);
p[ip][1] = abs(momentum(ip).x())<1.e-13 ? 0.0:double(momentum(ip).x()*amplitudeScale()/GeV);
p[ip][2] = abs(momentum(ip).y())<1.e-13 ? 0.0:double(momentum(ip).y()*amplitudeScale()/GeV);
p[ip][3] = abs(momentum(ip).z())<1.e-13 ? 0.0:double(momentum(ip).z()*amplitudeScale()/GeV);
}
// calculate amplitudes
vector<complex<double> > amplitudes;
MG_gg2ttxg process;
double factor=lastSHat()/GeV2;
process.initProc(MGParams_);
process.setMomenta(p);
process.sigmaKin(amplitudes, hel);
for (int iamp=0; iamp<int(amplitudes.size()); ++iamp)
amplitudes[iamp]*=sqrt(factor);
complex<double> matrixElement;
complex<double> i = complex<double>(0,1);
// calculate colour flows
if (a<5) matrixElement = 0.;
else if (a==5)
matrixElement = (-amplitudes[0] - amplitudes[5] + amplitudes[14] -
amplitudes[17] + amplitudes[15] +
i*(amplitudes[2] + amplitudes[4]));
else if (a==6)
matrixElement = (-amplitudes[3] + amplitudes[11] - amplitudes[14] -
amplitudes[16] - amplitudes[15] +
i*(-amplitudes[4] + amplitudes[10]));
else if (a==7)
matrixElement = ( amplitudes[0] - amplitudes[11] - amplitudes[12] +
amplitudes[17] + amplitudes[16] +
i*(-amplitudes[2] + amplitudes[9]));
else if (a==8)
matrixElement = (-amplitudes[6] + amplitudes[11] - amplitudes[14] -
amplitudes[16] - amplitudes[15]
+ i*(amplitudes[7] - amplitudes[9]));
else if (a==9)
matrixElement = (amplitudes[0] - amplitudes[11] - amplitudes[13] +
amplitudes[17] + amplitudes[16]
+ i*(amplitudes[1] - amplitudes[10]));
else if (a==10)
matrixElement = (-amplitudes[0] - amplitudes[8] + amplitudes[14] -
amplitudes[17] + amplitudes[15]
+ i*(-amplitudes[1] - amplitudes[7]));
else assert(false);
largeN = matrixElement;
return matrixElement;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudeggttbarg::persistentOutput(PersistentOStream &) const {}
void MatchboxAmplitudeggttbarg::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudeggttbarg,MatchboxAmplitude>
describeHerwigMatchboxAmplitudeggttbarg("Herwig::MatchboxAmplitudeggttbarg", "HwMatchboxBuiltin.so");
void MatchboxAmplitudeggttbarg::Init() {
static ClassDocumentation<MatchboxAmplitudeggttbarg> documentation
("MatchboxAmplitudeggttbarg");
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbarg.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbarg.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbarg.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeggttbarg.h
@@ -1,202 +1,194 @@
// -*- C++ -*-
//
// MatchboxAmplitudeggttbarg.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudeggttbarg_H
#define Herwig_MatchboxAmplitudeggttbarg_H
//
// This is the declaration of the MatchboxAmplitudeggttbarg class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
#include "MG_gg2ttxg.h"
#include "HelAmps_sm.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Alix Wilcock
*
* \brief MatchboxAmplitudeggttbarg
*/
class MatchboxAmplitudeggttbarg:
public MatchboxAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudeggttbarg();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudeggttbarg();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const {return 3; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 0; }
/**
* Return true, if this amplitude will not require colour correlations.
*/
virtual bool noCorrelations() const { return true; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
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();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudeggttbarg & operator=(const MatchboxAmplitudeggttbarg &) = delete;
/**
* Containers for external particle momenta
*/
double mom0 [4];
double mom1 [4];
double mom2 [4];
double mom3 [4];
double mom4 [4];
/**
* Fill MGParams_ with Herwig values of parameters
*/
void setupParams(map<string, double> & MGParams);
/**
* Stores parameters needed in MG_process
*/
map<string,double> MGParams_;
};
}
#endif /* Herwig_MatchboxAmplitudeggttbarg_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbar.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbar.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbar.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbar.cc
@@ -1,257 +1,253 @@
// -*- C++ -*-
//
// MatchboxAmplitudehbbbar.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudehbbbar class.
//
#include "MatchboxAmplitudehbbbar.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudehbbbar::MatchboxAmplitudehbbbar() {}
-MatchboxAmplitudehbbbar::~MatchboxAmplitudehbbbar() {}
-
IBPtr MatchboxAmplitudehbbbar::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudehbbbar::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudehbbbar::doinit() {
MatchboxAmplitude::doinit();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
nPoints(3);;
}
void MatchboxAmplitudehbbbar::doinitrun() {
MatchboxAmplitude::doinitrun();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
nPoints(3);
}
bool MatchboxAmplitudehbbbar::canHandle(const PDVector& proc) const {
if ( proc.size() != 3 )
return false;
PDVector xproc = proc;
PDVector::iterator q=xproc.begin();
for (; q!=xproc.end(); ++q){
if ((**q).id()==1 ||
(**q).id()==2 ||
(**q).id()==3 ||
(**q).id()==4 ||
(**q).id()==5)
break;
}
if(q==xproc.end()) return false;
int qid = (**q).id();
xproc.erase(q);
PDVector::iterator qb=xproc.begin();
for (; qb!=xproc.end(); ++qb){
if ((**qb).id()==-qid) break;
}
if(qb==xproc.end()) return false;
xproc.erase(qb);
PDVector::iterator h0=xproc.begin();
if (xproc.size()==1 && (**h0).id()==25) {return true;}
return false;
}
void MatchboxAmplitudehbbbar::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
//cout<<"prepare erreicht"<<endl;
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
//cout<<"momenta werden gesetzt"<<endl;
momentum(0,amplitudeMomentum(0));
momentum(1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudehbbbar::evaluate(size_t, const vector<int>& hel, Complex& largeN) {
unsigned int q=0;
unsigned int qbar=0;
cPDVector x=amplitudePartonData();
/*for (int i=0;i<3;++i){
cout<<"x["<<i<<"]: "<<x[i]->id()<<endl;
}*/
//cout<<"teilchenidentifizierung";
for (;q<amplitudePartonData().size();++q){if (x[q]->id()!= 25 && x[q]->id()>0 ) break;} //cout<<"x[q]"<<x[q]->id()<<" hel: "<<hel[q]<<endl;
for (;qbar<amplitudePartonData().size();++qbar){if (x[qbar]->id() ==-x[q]->id()) break;} //cout<<"x[qbar]"<<x[qbar]->id()<<" hel: "<<hel[qbar]<<endl;
double gw = sqrt(4*Constants::pi*SM().alphaEMMZ()) / sqrt(SM().sin2ThetaW());
long id=x[q]->id();
Energy Mf = 0*GeV;
switch(id){
case 1 : Mf = interfaceDMass; /*cout<<"d"<<ounit(Mf,GeV)<<endl;*/ break;
case 2 : Mf = interfaceUMass; /*cout<<"u"<<ounit(Mf,GeV)<<endl;*/ break;
case 3 : Mf = interfaceSMass; /*cout<<"s"<<ounit(Mf,GeV)<<endl;*/ break;
case 4 : Mf = interfaceCMass; /*cout<<"c"<<ounit(Mf,GeV)<<endl;*/ break;
case 5 : Mf = interfaceBMass; /*cout<<"b"<<ounit(Mf,GeV)<<endl;*/ break;
}
if (Mf==0*GeV)
throw Exception() << "Invalid settings in MatchboxAmplitudehbbbar -- zero fermion mass."
<< Exception::runerror;
double im=gw*Mf/2/MW;
Complex c = Complex(0.,im);
//cout<<"c: "<<c<<endl;
//cout<<"largeN wird berechnet werden";
//cout<<"plusproduct"<<plusProduct(qbar,q)<<endl;
//cout<<"minusproduct"<<minusProduct(qbar,q)<<endl;
if (hel[qbar]==-hel[q]&& hel[q]==1){
largeN = 0;
//cout<<"largeN plus hat geklappt"<<largeN;
return(largeN);
}
if (hel[qbar]==-hel[q]&& hel[q]==-1){
largeN = 0;
//cout<<"largeN plus hat geklappt"<<largeN;
return(largeN);
}
if (hel[qbar]==hel[q] && hel[q]==1){
largeN = c*(plusProduct(qbar,q));
//cout<<"largeN plus hat geklappt"<<largeN;
return(largeN);
}
if (hel[qbar]==hel[q] && hel[q]==-1){
largeN = c*(minusProduct(qbar,q));
//cout<<"largeN minus hat geklappt"<<largeN;
return(largeN);
}
assert(false);
return 0;
}
Complex MatchboxAmplitudehbbbar::evaluateOneLoop(size_t, const vector<int>& hel) {
Complex res = 0;
int q=0;
int qbar=0;
cPDVector x=amplitudePartonData();
for (;q<3;++q){if (x[q]->id()!= 25 && x[q]->id()>0 ) break;}
for (;qbar<3;++qbar){if (x[qbar]->id() ==-x[q]->id()) break;}
double gw = sqrt(4*Constants::pi*SM().alphaEMMZ()) / sqrt(SM().sin2ThetaW());
long id=x[q]->id();
Energy Mf = 0*GeV;
switch(id){
case 1 : Mf = interfaceDMass; break;
case 2 : Mf = interfaceUMass; break;
case 3 : Mf = interfaceSMass; break;
case 4 : Mf = interfaceCMass; break;
case 5 : Mf = interfaceBMass; break;
}
if (Mf==0*GeV)
throw Exception() << "Invalid settings in MatchboxAmplitudehbbbar -- zero fermion mass."
<< Exception::runerror;
double loop = SM().alphaS()*CF/2/Constants::pi ; //one-loop-Factor
double bornim = gw*Mf/2/MW; //constant factor from born
double real = loop*bornim;
Complex c = Complex(real,0.);
if (hel[qbar]==-hel[q]&& hel[q]==1){
res = 0;
return(res);
}
if (hel[qbar]==-hel[q]&& hel[q]==-1){
res = 0;
return(res);
}
if (hel[qbar]==hel[q] && hel[q]==1){
res = c*(plusProduct(qbar,q));
return(res);
}
if (hel[qbar]==hel[q] && hel[q]==-1){
res = c*(minusProduct(qbar,q));
return(res);
}
assert(false);
return 0;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudehbbbar::persistentOutput(PersistentOStream &os) const {
os << ounit(interfaceUMass,GeV)<< ounit(interfaceDMass,GeV)<< ounit(interfaceSMass,GeV)<< ounit(interfaceCMass,GeV)<< ounit(interfaceBMass,GeV);
}
void MatchboxAmplitudehbbbar::persistentInput(PersistentIStream &is, int) {
is >> iunit(interfaceUMass,GeV)>> iunit(interfaceDMass,GeV)>> iunit(interfaceSMass,GeV)>> iunit(interfaceCMass,GeV)>> iunit(interfaceBMass,GeV);
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudehbbbar,MatchboxAmplitude>
describeHerwigMatchboxAmplitudehbbbar("Herwig::MatchboxAmplitudehbbbar", "HwMatchboxBuiltin.so");
void MatchboxAmplitudehbbbar::Init() {
static ClassDocumentation<MatchboxAmplitudehbbbar> documentation
("MatchboxAmplitudehbbbar");
static Parameter<MatchboxAmplitudehbbbar,Energy> interfaceUMass
("interfaceUMass",
"The up quark mass to be used in the amplitude.",
&MatchboxAmplitudehbbbar::interfaceUMass, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<MatchboxAmplitudehbbbar,Energy> interfaceDMass
("interfaceDMass",
"The down quark mass to be used in the amplitude.",
&MatchboxAmplitudehbbbar::interfaceDMass, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<MatchboxAmplitudehbbbar,Energy> interfaceSMass
("interfaceSMass",
"The strange quark mass to be used in the amplitude.",
&MatchboxAmplitudehbbbar::interfaceSMass, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<MatchboxAmplitudehbbbar,Energy> interfaceCMass
("interfaceCMass",
"The charm quark mass to be used in the amplitude.",
&MatchboxAmplitudehbbbar::interfaceCMass, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<MatchboxAmplitudehbbbar,Energy> interfaceBMass
("interfaceBMass",
"The bottom quark mass to be used in the amplitude.",
&MatchboxAmplitudehbbbar::interfaceBMass, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbar.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbar.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbar.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbar.h
@@ -1,208 +1,200 @@
// -*- C++ -*-
//
// MatchboxAmplitudebbbarh.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudehbbbar_H
#define Herwig_MatchboxAmplitudehbbbar_H
//
// This is the declaration of the MatchboxAmplitudehbbbar class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
*
*
* \brief MatchboxAmplitudehbbbar
*/
class MatchboxAmplitudehbbbar:
public MatchboxAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudehbbbar();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudehbbbar();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 0; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 1; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return true; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluateOneLoop(size_t, const vector<int>&);
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
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();
//@}
private:
/*
* The interfaced up quark mass
*/
Energy interfaceUMass;
/*
* The interfaced down quark mass
*/
Energy interfaceDMass;
/*
* The interfaced strange quark mass
*/
Energy interfaceSMass;
/*
* The interfaced charm quark mass
*/
Energy interfaceCMass;
/*
* The interfaced bottom quark mass
*/
Energy interfaceBMass;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudehbbbar & operator=(const MatchboxAmplitudehbbbar &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudehbbbar_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbarg.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbarg.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbarg.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbarg.cc
@@ -1,248 +1,244 @@
// -*- C++ -*-
//
// MatchboxAmplitudehbbbarg.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudehbbbarg class.
//
#include "MatchboxAmplitudehbbbarg.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudehbbbarg::MatchboxAmplitudehbbbarg() {}
-MatchboxAmplitudehbbbarg::~MatchboxAmplitudehbbbarg() {}
-
IBPtr MatchboxAmplitudehbbbarg::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudehbbbarg::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudehbbbarg::doinit() {
MatchboxAmplitude::doinit();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
nPoints(4);;
}
void MatchboxAmplitudehbbbarg::doinitrun() {
MatchboxAmplitude::doinitrun();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
nPoints(4);
}
bool MatchboxAmplitudehbbbarg::canHandle(const PDVector& proc) const {
if ( proc.size() != 4 )
return false;
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
/*for (PDVector::iterator x=xproc.begin(); x!=xproc.end(); ++x){
cout<<"xproc: "<<(**x).id()<<endl;
}
cout<<endl;*/
PDVector::iterator q=xproc.begin();
for (; q!=xproc.end(); ++q){
if ((**q).id()==1 ||
(**q).id()==2 ||
(**q).id()==3 ||
(**q).id()==4 ||
(**q).id()==5)
break;
//cout<<"kein Quark gefunden";
}
if(q==xproc.end()) return false;
int qid = (**q).id(); //cout<<"qid ="<<qid<<endl;
xproc.erase(q);
PDVector::iterator qb=xproc.begin();
for (; qb!=xproc.end(); ++qb){
if ((**qb).id()==-qid /*|| (**qb).id()==qid*/ ){/*cout<<"qbid = "<<(**qb).id()<<endl; cout<<"kein antiquark gefunden!"<<endl;*/ break;}
}
if(qb==xproc.end()){/*cout<<"kein antiquark gefunden"<<endl;*/ return false;}
xproc.erase(qb);
for (PDVector::iterator g=xproc.begin(); g!=xproc.end(); ++g){
if ((**g).id()==21){xproc.erase(g); break; }
}
if (xproc.size()==1 && (**xproc.begin()).id()==25) {return true;}
return false;
}
void MatchboxAmplitudehbbbarg::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
/*setupLeptons(0,amplitudeMomentum(0),
1,amplitudeMomentum(1));*/
momentum(0,amplitudeMomentum(0));
momentum(1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudehbbbarg::evaluate(size_t, const vector<int>& hel, Complex& largeN) {
unsigned int q=0;
unsigned int qbar=0;
unsigned int g=0;
cPDVector x=amplitudePartonData();
for (;q<amplitudePartonData().size();++q){if (x[q]->id()!= 25 && x[q]->id()>0 ) break;}
for (;qbar<amplitudePartonData().size();++qbar){if (x[qbar]->id() ==-x[q]->id()) break;}
for (;g<amplitudePartonData().size();++g){if (x[g]->id() == 21) break;}
double gw = sqrt(4*Constants::pi*SM().alphaEMMZ()) / sqrt(SM().sin2ThetaW());
double gs = sqrt(4*Constants::pi*SM().alphaS());
//double alphaS = SM().alphaS();
//double v= 2*MW/gw/sqrt(mu2()) ; //Auf mu normierter VakuumErwartungswert
//double c = gs*alphaS/3/Constants::pi/v;
long id=x[q]->id();
Energy Mf = 0*GeV;
switch(id){
case 1 : Mf = interfaceDMass; /*cout<<"d"<<ounit(Mf,GeV)<<endl;*/ break;
case 2 : Mf = interfaceUMass; /*cout<<"u"<<ounit(Mf,GeV)<<endl;*/ break;
case 3 : Mf = interfaceSMass; /*cout<<"s"<<ounit(Mf,GeV)<<endl;*/ break;
case 4 : Mf = interfaceCMass; /*cout<<"c"<<ounit(Mf,GeV)<<endl;*/ break;
case 5 : Mf = interfaceBMass; /*cout<<"b"<<ounit(Mf,GeV)<<endl;*/ break;
}
if (Mf==0*GeV)
throw Exception() << "Invalid settings in MatchboxAmplitudehbbbarg -- zero fermion mass."
<< Exception::runerror;
Complex c2= Complex(0.,gw*gs*Mf/MW/sqrt(2));
//qghq Prozesse mit Quark als "Zwischenteilchen" aus qghq.nb
if(hel[qbar]==+1 && hel[q]==+1 && hel[g]==-1){
largeN = -c2*minusProduct(q,qbar)*minusProduct(q,qbar)/minusProduct(q,g)/minusProduct(qbar,g);
return(largeN);
}
if(hel[qbar]==+1 && hel[q]==+1 && hel[g]==+1){
largeN = c2*(minusProduct(qbar,g)/plusProduct(q,g)+
minusProduct(q,g)/plusProduct(qbar,g)-
invariant(qbar,q)/plusProduct(q,g)/plusProduct(qbar,g));
return(largeN);
}
if(hel[qbar]==-1 && hel[q]==-1 && hel[g]==+1){
largeN = c2*plusProduct(q,qbar)*plusProduct(q,qbar)/plusProduct(q,g)/plusProduct(qbar,g);
return(largeN);
}
if(hel[qbar]==-1 && hel[q]==-1 && hel[g]==-1){
largeN = -c2*(plusProduct(qbar,g)/minusProduct(q,g)+
plusProduct(q,g)/minusProduct(qbar,g)-
invariant(qbar,q)/minusProduct(q,g)/minusProduct(qbar,g));
return(largeN);
}
if(hel[qbar]==-hel[q]){
largeN = 0;
return(largeN);
}
// Viel zu hohe Ordnnung in alphaS!!! Vielleicht spaeter per Interface dazuschaltbar??
// //mpm verdrehte vorzeichen wegen simons spinordef q=p qbar=q; g=r gluonhelizitaeten bleiben bleiben
// if(hel[qbar]==+1 && hel[q]==-1 && hel[g]==-1){
// largeN = c*minusProduct(q,qbar)*plusProduct(q,g)*plusProduct(q,g)/(invariant(q,qbar));
// return(largeN);
// }
// //mpp
// if(hel[qbar]==1 && hel[q]==-1 && hel[g]==1){
// largeN = c*minusProduct(qbar,g)*minusProduct(qbar,g)*plusProduct(q,qbar)/(invariant(q,qbar));
// return(largeN);
// }
// //pmm
// if(hel[qbar]==-1 && hel[q]==1 && hel[g]==-1){
// largeN = -c*minusProduct(q,qbar)*plusProduct(qbar,g)*plusProduct(qbar,g)/(invariant(q,qbar));
// return(largeN);
// }
// //pmp
// if(hel[qbar]==-1 && hel[q]==1 && hel[g]==1){
// largeN = -c*minusProduct(q,g)*minusProduct(q,g)*plusProduct(q,qbar)/(invariant(q,qbar));
// return(largeN);
// }
assert(false);
return 0;
}
/*Complex MatchboxAmplitudehbbbarg::evaluateOneLoop(size_t, const vector<int>& hel) {
}*/
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudehbbbarg::persistentOutput(PersistentOStream &os) const {
os << ounit(interfaceUMass,GeV)<< ounit(interfaceDMass,GeV)<< ounit(interfaceSMass,GeV)<< ounit(interfaceCMass,GeV)<< ounit(interfaceBMass,GeV);
}
void MatchboxAmplitudehbbbarg::persistentInput(PersistentIStream &is, int) {
is >> iunit(interfaceUMass,GeV)>> iunit(interfaceDMass,GeV)>> iunit(interfaceSMass,GeV)>> iunit(interfaceCMass,GeV)>> iunit(interfaceBMass,GeV);
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudehbbbarg,MatchboxAmplitude>
describeHerwigMatchboxAmplitudehbbbarg("Herwig::MatchboxAmplitudehbbbarg", "HwMatchboxBuiltin.so");
void MatchboxAmplitudehbbbarg::Init() {
static ClassDocumentation<MatchboxAmplitudehbbbarg> documentation
("MatchboxAmplitudehbbbarg");
static Parameter<MatchboxAmplitudehbbbarg,Energy> interfaceUMass
("interfaceUMass",
"The up quark mass to be used in the amplitude.",
&MatchboxAmplitudehbbbarg::interfaceUMass, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<MatchboxAmplitudehbbbarg,Energy> interfaceDMass
("interfaceDMass",
"The down quark mass to be used in the amplitude.",
&MatchboxAmplitudehbbbarg::interfaceDMass, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<MatchboxAmplitudehbbbarg,Energy> interfaceSMass
("interfaceSMass",
"The strange quark mass to be used in the amplitude.",
&MatchboxAmplitudehbbbarg::interfaceSMass, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<MatchboxAmplitudehbbbarg,Energy> interfaceCMass
("interfaceCMass",
"The charm quark mass to be used in the amplitude.",
&MatchboxAmplitudehbbbarg::interfaceCMass, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<MatchboxAmplitudehbbbarg,Energy> interfaceBMass
("interfaceBMass",
"The bottom quark mass to be used in the amplitude.",
&MatchboxAmplitudehbbbarg::interfaceBMass, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbarg.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbarg.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbarg.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehbbbarg.h
@@ -1,208 +1,200 @@
// -*- C++ -*-
//
// MatchboxAmplitudehbbbarg.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudehbbbarg_H
#define Herwig_MatchboxAmplitudehbbbarg_H
//
// This is the declaration of the MatchboxAmplitudehbbbarg class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
*
*
* \brief MatchboxAmplitudehbbbarg
*/
class MatchboxAmplitudehbbbarg:
public MatchboxAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudehbbbarg();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudehbbbarg();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 1; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 1; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return true; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
//virtual Complex evaluateOneLoop(size_t, const vector<int>&);
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
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();
//@}
private:
/*
* The interfaced up quark mass
*/
Energy interfaceUMass;
/*
* The interfaced down quark mass
*/
Energy interfaceDMass;
/*
* The interfaced strange quark mass
*/
Energy interfaceSMass;
/*
* The interfaced charm quark mass
*/
Energy interfaceCMass;
/*
* The interfaced bottom quark mass
*/
Energy interfaceBMass;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudehbbbarg & operator=(const MatchboxAmplitudehbbbarg &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudehbbbarg_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehgg.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehgg.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehgg.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehgg.cc
@@ -1,156 +1,154 @@
// -*- C++ -*-
//
// MatchboxAmplitudehgg.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudehgg class.
//
#include "MatchboxAmplitudehgg.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinorHelicity.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/ParticleData.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudehgg::MatchboxAmplitudehgg()
: interfaceTHooft(126*GeV) {}
-MatchboxAmplitudehgg::~MatchboxAmplitudehgg() {}
-
IBPtr MatchboxAmplitudehgg::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudehgg::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudehgg::doinit() {
MatchboxAmplitude::doinit();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
nPoints(3);
}
void MatchboxAmplitudehgg::doinitrun() {
MatchboxAmplitude::doinitrun();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
nPoints(3);
}
bool MatchboxAmplitudehgg::canHandle(const PDVector& proc) const {
if ( proc.size() != 3 ) return false;
PDVector xproc = proc;
for (PDVector::iterator g=xproc.begin(); g!=xproc.end(); ++g){
if ((**g).id()==21) {xproc.erase(g); --g;}
}
if (xproc.size()==1 && (**xproc.begin()).id()==25) {return true;}
return false;
}
void MatchboxAmplitudehgg::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
momentum(0,amplitudeMomentum(0));
momentum(1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudehgg::evaluate(size_t, const vector<int>& hel, Complex& largeN) {
unsigned int g1=0;
unsigned int g2=0;
cPDVector x=amplitudePartonData();
for (;g1<amplitudePartonData().size();++g1){
if (x[g1]->id()==21) {
for (g2=g1+1;g2<amplitudePartonData().size();++g2){if (x[g2]->id()==21) break;}
break;
}
}
// wrong assignement of the particles. g1 and g2 have to be different gluons.
assert(g1!=g2);
double gw = sqrt(4*Constants::pi*SM().alphaEMMZ()) / sqrt(SM().sin2ThetaW());
double v= 2*MW/gw/sqrt(lastSHat());
Complex c = Complex (0.,-1.*SM().alphaS()/3/Constants::pi/v);
if (hel[g1]==-hel[g2]){
largeN=0;
return largeN;
}
if (hel[g1]==hel[g2] && hel[g1]==-1){
largeN=c*plusProduct(g1,g2)*plusProduct(g1,g2);
return largeN;
}
if (hel[g1]==hel[g2] && hel[g1]==1){
largeN=c*minusProduct(g1,g2)*minusProduct(g1,g2);
return largeN;
}
// unknown helicity configuration
assert(false);
return(0.);
}
Complex MatchboxAmplitudehgg::evaluateOneLoop(size_t a , const vector<int>& Hel) {
Complex E = SM().alphaS()/Constants::pi*11/4;
Complex largeN = 0.;
return (E*evaluate(a,Hel,largeN));
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudehgg::persistentOutput(PersistentOStream &os) const {
os << ounit(interfaceTHooft,GeV);
}
void MatchboxAmplitudehgg::persistentInput(PersistentIStream &is, int) {
is >> iunit(interfaceTHooft,GeV);
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudehgg,MatchboxAmplitude>
describeHerwigMatchboxAmplitudehgg("Herwig::MatchboxAmplitudehgg", "HwMatchboxBuiltin.so");
void MatchboxAmplitudehgg::Init() {
static ClassDocumentation<MatchboxAmplitudehgg> documentation
("MatchboxAmplitudehgg");
/* // not used guess leftover from validation (mu2() variation)
static Parameter<MatchboxAmplitudehgg,Energy> interfaceTHooft
("interfaceTHooft",
"The THooft Mass.",
&MatchboxAmplitudehgg::interfaceTHooft, GeV, 115.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
*/
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehgg.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehgg.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehgg.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehgg.h
@@ -1,190 +1,182 @@
// -*- C++ -*-
//
// MatchboxAmplitudehgg.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudehgg_H
#define Herwig_MatchboxAmplitudehgg_H
//
// This is the declaration of the MatchboxAmplitudehgg class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Benedikt Zimmermann
*
* \brief MatchboxAmplitudehgg
*/
class MatchboxAmplitudehgg:
public MatchboxAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudehgg();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudehgg();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 2; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 1; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return true; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluateOneLoop(size_t, const vector<int>&);
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
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();
//@}
private:
/*
* The interfaced THooftMass
*/
Energy interfaceTHooft;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudehgg & operator=(const MatchboxAmplitudehgg &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudehgg_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehggg.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehggg.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehggg.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehggg.cc
@@ -1,206 +1,204 @@
// -*- C++ -*-
//
// MatchboxAmplitudehggg.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudehggg class.
//
#include "MatchboxAmplitudehggg.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SpinorHelicity.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/ParticleData.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudehggg::MatchboxAmplitudehggg()
: interfaceTHooft(126*GeV) {}
-MatchboxAmplitudehggg::~MatchboxAmplitudehggg() {}
-
IBPtr MatchboxAmplitudehggg::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudehggg::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudehggg::doinit() {
MatchboxAmplitude::doinit();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
nPoints(4);
}
void MatchboxAmplitudehggg::doinitrun() {
MatchboxAmplitude::doinitrun();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
nPoints(4);
}
bool MatchboxAmplitudehggg::canHandle(const PDVector& proc) const {
if ( proc.size() != 4 ) return false;
PDVector xproc = proc;
for (PDVector::iterator g=xproc.begin(); g!=xproc.end(); ++g){
if ((**g).id()==21) {xproc.erase(g); --g;}
}
if (xproc.size()==1 && (**xproc.begin()).id()==25) {return true;}
return false;
}
void MatchboxAmplitudehggg::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
momentum(0,amplitudeMomentum(0));
momentum(1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudehggg::evaluate(size_t a, const vector<int>& hel, Complex& largeN) {
unsigned int p=0;
unsigned int q=0;
unsigned int r=0;
cPDVector x=amplitudePartonData();
for (;p<amplitudePartonData().size();++p){
if (x[p]->id()==21) {
for (q=p+1;q<amplitudePartonData().size();++q){
if (x[q]->id()==21){
for (r=q+1;r<amplitudePartonData().size();++r){if (x[r]->id()==21) break;}
}
break;}
break;
}
}
// Wrong particle assignment. There have to be three distinct Gluons p, q and r.
assert(!((p==q) || (p==r) || (q==r)));
double gw = sqrt(4*Constants::pi*SM().alphaEMMZ()) / sqrt(SM().sin2ThetaW());
double gs = sqrt(4*Constants::pi*SM().alphaS());
double v= 2*MW/gw/sqrt(lastSHat()) ;
Complex c = Complex (0.,0.);
// Assertion makes sure that there is no crossing, which causes a relative minus sign. If Assert -> new, more general code is needed
assert(amplitudeToColourMap()[1]==0 && amplitudeToColourMap()[2]==1 && amplitudeToColourMap()[3]==2 );
if (a==0){
c = Complex (0.,-1.)*sqrt(2.)*SM().alphaS()/3./Constants::pi/v*gs ;
}
else {
if (a==1){
c = Complex (0.,+1.)*sqrt(2.)*SM().alphaS()/3./Constants::pi/v*gs ;
}
else{
//The Colourbasis a is not appropriate for this process.
// hggg ~ f^{abc} -> ~ tr(t^a,t^b,t^c) - tr(t^a,t^c,t^b) -> a in {0,1}
assert(true);
}
}
if(hel[p]==+1 && hel[q]==+1 && hel[r]==+1){
largeN = c*(invariant(p,q)*invariant(p,q)+2*invariant(p,q)*invariant(p,r)
+invariant(p,r)*invariant(p,r)+2*invariant(p,q)*invariant(q,r)
+2*invariant(p,r)*invariant(q,r)+invariant(q,r)*invariant(q,r))
/plusProduct(p,q)/plusProduct(p,r)/plusProduct(q,r);
return(largeN);
}
if(hel[p]==+1 && hel[q]==+1 && hel[r]==-1){
largeN = -c*minusProduct(p,q)*minusProduct(p,q)*minusProduct(p,q)/minusProduct(p,r)/minusProduct(q,r);
return(largeN);
}
if(hel[p]==+1 && hel[q]==-1 && hel[r]==+1){
largeN = -c*minusProduct(p,r)*minusProduct(p,r)*minusProduct(p,r)/minusProduct(p,q)/minusProduct(q,r);
return(largeN);
}
if(hel[p]==+1 && hel[q]==-1 && hel[r]==-1){
largeN = c*plusProduct(q,r)*plusProduct(q,r)*plusProduct(q,r)/plusProduct(p,q)/plusProduct(p,r);
return(largeN);
}
if(hel[p]==-1 && hel[q]==+1 && hel[r]==+1){
largeN = -c*minusProduct(q,r)*minusProduct(q,r)*minusProduct(q,r)/minusProduct(p,q)/minusProduct(p,r);
return(largeN);
}
if(hel[p]==-1 && hel[q]==+1 && hel[r]==-1){
largeN = c*plusProduct(p,r)*plusProduct(p,r)*plusProduct(p,r)/plusProduct(p,q)/plusProduct(q,r);
return(largeN);
}
if(hel[p]==-1 && hel[q]==-1 && hel[r]==+1){
largeN = c*plusProduct(p,q)*plusProduct(p,q)*plusProduct(p,q)/plusProduct(p,r)/plusProduct(q,r);
return(largeN);
}
if(hel[p]==-1 && hel[q]==-1 && hel[r]==-1){
largeN = -c*(invariant(p,q)*invariant(p,q)+2*invariant(p,q)*invariant(p,r)
+invariant(p,r)*invariant(p,r)+2*invariant(p,q)*invariant(q,r)
+2*invariant(p,r)*invariant(q,r)+invariant(q,r)*invariant(q,r))
/plusProduct(p,q)/plusProduct(p,r)/plusProduct(q,r);
return(largeN);
}
// Unknown helicity configuration
assert(false);
return(0.);
}
/*Complex MatchboxAmplitudehggg::evaluateOneLoop(size_t, const vector<int>& hel) {
}*/
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudehggg::persistentOutput(PersistentOStream &os) const {
os << ounit(interfaceTHooft,GeV);
}
void MatchboxAmplitudehggg::persistentInput(PersistentIStream &is, int) {
is >> iunit(interfaceTHooft,GeV);
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudehggg,MatchboxAmplitude>
describeHerwigMatchboxAmplitudehggg("Herwig::MatchboxAmplitudehggg", "HwMatchboxBuiltin.so");
void MatchboxAmplitudehggg::Init() {
static ClassDocumentation<MatchboxAmplitudehggg> documentation
("MatchboxAmplitudehggg");
/* // not used guess leftover from validation (mu2() variation)
static Parameter<MatchboxAmplitudehggg,Energy> interfaceTHooft
("interfaceTHooft",
"The THooft Mass.",
&MatchboxAmplitudehggg::interfaceTHooft, GeV, 115.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
*/
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehggg.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehggg.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehggg.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehggg.h
@@ -1,191 +1,183 @@
// -*- C++ -*-
//
// MatchboxAmplitudehggg.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudehggg_H
#define Herwig_MatchboxAmplitudehggg_H
//
// This is the declaration of the MatchboxAmplitudehggg class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Benedikt Zimmermann
*
* \brief MatchboxAmplitudehggg
*/
class MatchboxAmplitudehggg:
public MatchboxAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudehggg();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudehggg();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 3; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 1; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
//virtual Complex evaluateOneLoop(size_t, const vector<int>&);
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
public:
/*
* The interfaced THooftMass
*/
Energy interfaceTHooft;
/** @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();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudehggg & operator=(const MatchboxAmplitudehggg &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudehggg_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehqqbarg.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehqqbarg.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehqqbarg.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehqqbarg.cc
@@ -1,185 +1,183 @@
// -*- C++ -*-
//
// MatchboxAmplitudehqqbarg.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudehqqbarg class.
//
#include "MatchboxAmplitudehqqbarg.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudehqqbarg::MatchboxAmplitudehqqbarg()
: interfaceTHooft(126*GeV) {}
-MatchboxAmplitudehqqbarg::~MatchboxAmplitudehqqbarg() {}
-
IBPtr MatchboxAmplitudehqqbarg::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudehqqbarg::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudehqqbarg::doinit() {
MatchboxAmplitude::doinit();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
nPoints(4);;
}
void MatchboxAmplitudehqqbarg::doinitrun() {
MatchboxAmplitude::doinitrun();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
nPoints(4);
}
bool MatchboxAmplitudehqqbarg::canHandle(const PDVector& proc) const {
if ( proc.size() != 4 )
return false;
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
PDVector::iterator q=xproc.begin();
for (; q!=xproc.end(); ++q){
if ((**q).id()==1 ||
(**q).id()==2 ||
(**q).id()==3 ||
(**q).id()==4 ||
(**q).id()==5)
break;
}
if(q==xproc.end()) return false;
int qid = (**q).id();
xproc.erase(q);
PDVector::iterator qb=xproc.begin();
for (; qb!=xproc.end(); ++qb){
if ((**qb).id()==-qid ){break;}
}
if(qb==xproc.end()){ return false;}
xproc.erase(qb);
for (PDVector::iterator g=xproc.begin(); g!=xproc.end(); ++g){
if ((**g).id()==21){xproc.erase(g); break; }
}
if (xproc.size()==1 && (**xproc.begin()).id()==25) {return true;}
return false;
}
void MatchboxAmplitudehqqbarg::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
momentum(0,amplitudeMomentum(0));
momentum(1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudehqqbarg::evaluate(size_t, const vector<int>& hel, Complex& largeN) {
unsigned int q=0;
unsigned int qbar=0;
unsigned int g=0;
cPDVector x=amplitudePartonData();
for (;q<amplitudePartonData().size();++q){if (x[q]->id()!= 25 && x[q]->id()>0 ) break;}
for (;qbar<amplitudePartonData().size();++qbar){if (x[qbar]->id() ==-x[q]->id()) break;}
for (;g<amplitudePartonData().size();++g){if (x[g]->id() == 21) break;}
double gw = sqrt(4*Constants::pi*SM().alphaEMMZ()) / sqrt(SM().sin2ThetaW());
double gs = sqrt(4*Constants::pi*SM().alphaS());
double alphaS = SM().alphaS();
double v= 2*MW/gw/sqrt(lastSHat()) ;
double c = gs*alphaS/3/sqrt(2.)/Constants::pi/v;
if(hel[qbar]==hel[q]){
largeN = 0;
return(largeN);
}
if(hel[qbar]==+1 && hel[q]==-1 && hel[g]==-1){
largeN = -c*plusProduct(qbar,g)*plusProduct(qbar,g)/(plusProduct(q,qbar));
return(largeN);
}
if(hel[qbar]==1 && hel[q]==-1 && hel[g]==1){
largeN = -c*minusProduct(q,g)*minusProduct(q,g)/(minusProduct(q,qbar));
return(largeN);
}
if(hel[qbar]==-1 && hel[q]==1 && hel[g]==-1){
largeN = c*plusProduct(q,g)*plusProduct(q,g)/(plusProduct(q,qbar));
return(largeN);
}
if(hel[qbar]==-1 && hel[q]==1 && hel[g]==1){
largeN = c*minusProduct(qbar,g)*minusProduct(qbar,g)/(minusProduct(q,qbar));
return(largeN);
}
// Unknown helicity configuration
assert(false);
return(0.);
}
/*Complex MatchboxAmplitudehqqbarg::evaluateOneLoop(size_t, const vector<int>& hel) {
}*/
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudehqqbarg::persistentOutput(PersistentOStream &os) const {
os << ounit(interfaceTHooft,GeV);
}
void MatchboxAmplitudehqqbarg::persistentInput(PersistentIStream &is, int) {
is >> iunit(interfaceTHooft,GeV);
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudehqqbarg,MatchboxAmplitude>
describeHerwigMatchboxAmplitudehqqbarg("Herwig::MatchboxAmplitudehqqbarg", "HwMatchboxBuiltin.so");
void MatchboxAmplitudehqqbarg::Init() {
static ClassDocumentation<MatchboxAmplitudehqqbarg> documentation
("MatchboxAmplitudehqqbarg");
/* // not used guess leftover from validation (mu2() variation)
static Parameter<MatchboxAmplitudehqqbarg,Energy> interfaceTHooft
("interfaceTHooft",
"The THooft Mass.",
&MatchboxAmplitudehqqbarg::interfaceTHooft, GeV, 115.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
*/
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehqqbarg.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehqqbarg.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehqqbarg.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudehqqbarg.h
@@ -1,189 +1,181 @@
// -*- C++ -*-
//
// MatchboxAmplitudehqqbarg.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudehqqbarg_H
#define Herwig_MatchboxAmplitudehqqbarg_H
//
// This is the declaration of the MatchboxAmplitudehqqbarg class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Benedikt Zimmermann
*
* \brief MatchboxAmplitudehqqbarg
*/
class MatchboxAmplitudehqqbarg:
public MatchboxAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudehqqbarg();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudehqqbarg();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 3; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 1; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
//virtual Complex evaluateOneLoop(size_t, const vector<int>&);
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
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();
//@}
private:
/*
* The interfaced THooftMass
*/
Energy interfaceTHooft;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudehqqbarg & operator=(const MatchboxAmplitudehqqbarg &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudehqqbarg_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbar.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbar.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbar.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbar.cc
@@ -1,241 +1,239 @@
// -*- C++ -*-
//
// MatchboxAmplitudellbarqqbar.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudellbarqqbar class.
//
#include "MatchboxAmplitudellbarqqbar.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudellbarqqbar::MatchboxAmplitudellbarqqbar() {}
-MatchboxAmplitudellbarqqbar::~MatchboxAmplitudellbarqqbar() {}
-
IBPtr MatchboxAmplitudellbarqqbar::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudellbarqqbar::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudellbarqqbar::doinit() {
MatchboxZGammaAmplitude::doinit();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
nPoints(4);
}
void MatchboxAmplitudellbarqqbar::doinitrun() {
MatchboxZGammaAmplitude::doinitrun();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
nPoints(4);
}
bool MatchboxAmplitudellbarqqbar::canHandle(const PDVector& proc) const {
if ( proc.size() != 4 )
return false;
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
PDVector::iterator lepton = xproc.begin();
long leptonId = 0;
for ( ; lepton != xproc.end(); ++lepton )
if ( (**lepton).id() == 11 ||
(**lepton).id() == 13 ||
(**lepton).id() == 15 ) {
break;
}
if ( lepton == xproc.end() )
return false;
leptonId = (**lepton).id();
xproc.erase(lepton);
PDVector::iterator antiLepton = xproc.begin();
for ( ; antiLepton != xproc.end(); ++antiLepton )
if ( (**antiLepton).id() == -leptonId ) {
break;
}
if ( antiLepton == xproc.end() )
return false;
xproc.erase(antiLepton);
PDVector::iterator quark = xproc.begin();
long quarkId = 0;
for ( ; quark != xproc.end(); ++quark )
if ( abs((**quark).id()) < 7 &&
(**quark).id() > 0 ) {
break;
}
if ( quark == xproc.end() )
return false;
quarkId = (**quark).id();
xproc.erase(quark);
PDVector::iterator antiQuark = xproc.begin();
for ( ; antiQuark != xproc.end(); ++antiQuark )
if ( (**antiQuark).id() == -quarkId ) {
break;
}
if ( antiQuark == xproc.end() )
return false;
xproc.erase(antiQuark);
return xproc.empty();
}
void MatchboxAmplitudellbarqqbar::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxZGammaAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
setupLeptons(0,amplitudeMomentum(0),
1,amplitudeMomentum(1));
setupQuarks(2,amplitudeMomentum(2),
3,amplitudeMomentum(3));
MatchboxZGammaAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudellbarqqbar::evaluate(size_t, const vector<int>& hel, Complex& largeN) {
if ( abs(hel[2])+abs(hel[3]) != 2 ) {
largeN = 0.;
return 0.;
}
const LorentzVector<Complex>& leptonLeft
= llbarLeftCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& leptonRight
= llbarRightCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& quarkLeft
= qqbarLeftCurrent(2,hel[2],3,hel[3]);
const LorentzVector<Complex>& quarkRight
= qqbarRightCurrent(2,hel[2],3,hel[3]);
Complex LL = leptonLeft.dot( quarkLeft );
Complex RL = leptonRight.dot( quarkLeft );
Complex LR = leptonLeft.dot( quarkRight );
Complex RR = leptonRight.dot( quarkRight );
double bProp = (amplitudeMomentum(0)+amplitudeMomentum(1)).m2()/lastSHat();
Complex gamma = 0.0;
if ( includeGamma() )
gamma = Complex(0.,-1.)*(-amplitudePartonData()[2]->iCharge()/3.)*
(LL + RL + LR + RR)/bProp;
bool up = abs(amplitudePartonData()[2]->id()) % 2 == 0;
Complex Z = 0.0;
if ( includeZ() )
Z = Complex(0.,-1.)*
(standardModel()->le()*(up ? standardModel()->lu() : standardModel()->ld())*LL +
standardModel()->re()*(up ? standardModel()->lu() : standardModel()->ld())*RL +
standardModel()->le()*(up ? standardModel()->ru() : standardModel()->rd())*LR +
standardModel()->re()*(up ? standardModel()->ru() : standardModel()->rd())*RR)/
Complex(bProp-sqr(MZ)/lastSHat(),MZ*GZ/lastSHat());
Complex res = 4.*Constants::pi*SM().alphaEMMZ()*(gamma+Z);
largeN = res;
return res;
}
Complex MatchboxAmplitudellbarqqbar::evaluateOneLoop(size_t, const vector<int>& hel) {
const LorentzVector<Complex>& leptonLeft
= llbarLeftCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& leptonRight
= llbarRightCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& quarkLeft
= qqbarLeftOneLoopCurrent(2,hel[2],3,hel[3]);
const LorentzVector<Complex>& quarkRight
= qqbarRightOneLoopCurrent(2,hel[2],3,hel[3]);
Complex LL = leptonLeft.dot( quarkLeft );
Complex RL = leptonRight.dot( quarkLeft );
Complex LR = leptonLeft.dot( quarkRight );
Complex RR = leptonRight.dot( quarkRight );
double bProp = (amplitudeMomentum(0)+amplitudeMomentum(1)).m2()/lastSHat();
Complex gamma = 0.0;
if ( includeGamma() )
gamma = Complex(0.,-1.)*(-amplitudePartonData()[2]->iCharge()/3.)*
(LL + RL + LR + RR)/bProp;
bool up = abs(amplitudePartonData()[2]->id()) % 2 == 0;
Complex Z = 0.0;
if ( includeZ() )
Z = Complex(0.,-1.)*
(standardModel()->le()*(up ? standardModel()->lu() : standardModel()->ld())*LL +
standardModel()->re()*(up ? standardModel()->lu() : standardModel()->ld())*RL +
standardModel()->le()*(up ? standardModel()->ru() : standardModel()->rd())*LR +
standardModel()->re()*(up ? standardModel()->ru() : standardModel()->rd())*RR)/
Complex(bProp-sqr(MZ)/lastSHat(),MZ*GZ/lastSHat());
Complex res = (SM().alphaS()/(2.*Constants::pi))*4.*Constants::pi*SM().alphaEMMZ()*(gamma+Z);
return res;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudellbarqqbar::persistentOutput(PersistentOStream &) const {}
void MatchboxAmplitudellbarqqbar::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudellbarqqbar,MatchboxZGammaAmplitude>
describeHerwigMatchboxAmplitudellbarqqbar("Herwig::MatchboxAmplitudellbarqqbar", "HwMatchboxBuiltin.so");
void MatchboxAmplitudellbarqqbar::Init() {
static ClassDocumentation<MatchboxAmplitudellbarqqbar> documentation
("MatchboxAmplitudellbarqqbar");
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbar.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbar.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbar.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbar.h
@@ -1,186 +1,178 @@
// -*- C++ -*-
//
// MatchboxAmplitudellbarqqbar.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudellbarqqbar_H
#define Herwig_MatchboxAmplitudellbarqqbar_H
//
// This is the declaration of the MatchboxAmplitudellbarqqbar class.
//
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxAmplitudellbarqqbar
*/
class MatchboxAmplitudellbarqqbar:
public MatchboxZGammaAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudellbarqqbar();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudellbarqqbar();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 0; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 2; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return true; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluateOneLoop(size_t, const vector<int>&);
/**
* Return true if one loop corrections are given in the conventions of everything expanded - this is currently the only convention available in DipoleMIOperator.cc
*/
virtual bool isExpanded() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxZGammaAmplitude::flushCaches();
}
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();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudellbarqqbar & operator=(const MatchboxAmplitudellbarqqbar &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudellbarqqbar_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarg.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarg.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarg.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarg.cc
@@ -1,255 +1,253 @@
// -*- C++ -*-
//
// MatchboxAmplitudellbarqqbarg.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudellbarqqbarg class.
//
#include "MatchboxAmplitudellbarqqbarg.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudellbarqqbarg::MatchboxAmplitudellbarqqbarg() {}
-MatchboxAmplitudellbarqqbarg::~MatchboxAmplitudellbarqqbarg() {}
-
IBPtr MatchboxAmplitudellbarqqbarg::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudellbarqqbarg::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudellbarqqbarg::doinit() {
MatchboxZGammaAmplitude::doinit();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
nPoints(5);
}
void MatchboxAmplitudellbarqqbarg::doinitrun() {
MatchboxZGammaAmplitude::doinitrun();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
nPoints(5);
}
bool MatchboxAmplitudellbarqqbarg::canHandle(const PDVector& proc) const {
if ( proc.size() != 5 )
return false;
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
PDVector::iterator lepton = xproc.begin();
long leptonId = 0;
for ( ; lepton != xproc.end(); ++lepton )
if ( (**lepton).id() == 11 ||
(**lepton).id() == 13 ||
(**lepton).id() == 15 ) {
break;
}
if ( lepton == xproc.end() )
return false;
leptonId = (**lepton).id();
xproc.erase(lepton);
PDVector::iterator antiLepton = xproc.begin();
for ( ; antiLepton != xproc.end(); ++antiLepton )
if ( (**antiLepton).id() == -leptonId ) {
break;
}
if ( antiLepton == xproc.end() )
return false;
xproc.erase(antiLepton);
PDVector::iterator quark = xproc.begin();
long quarkId = 0;
for ( ; quark != xproc.end(); ++quark )
if ( abs((**quark).id()) < 7 &&
(**quark).id() > 0 ) {
break;
}
if ( quark == xproc.end() )
return false;
quarkId = (**quark).id();
xproc.erase(quark);
PDVector::iterator antiQuark = xproc.begin();
for ( ; antiQuark != xproc.end(); ++antiQuark )
if ( (**antiQuark).id() == -quarkId ) {
break;
}
if ( antiQuark == xproc.end() )
return false;
xproc.erase(antiQuark);
if ( xproc.size() != 1 )
return false;
return xproc[0]->id() == 21;
}
void MatchboxAmplitudellbarqqbarg::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxZGammaAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
setupLeptons(0,amplitudeMomentum(0),
1,amplitudeMomentum(1));
setupQuarks(2,amplitudeMomentum(2),
3,amplitudeMomentum(3));
momentum(4,amplitudeMomentum(4));
MatchboxZGammaAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudellbarqqbarg::evaluate(size_t, const vector<int>& hel, Complex& largeN) {
assert(nPoints() == 5);
if ( abs(hel[2])+abs(hel[3]) != 2 ) {
largeN = 0.;
return 0.;
}
const LorentzVector<Complex>& leptonLeft
= llbarLeftCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& leptonRight
= llbarRightCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& quarkLeft
= qqbargLeftCurrent(2,hel[2],3,hel[3],4,hel[4]);
const LorentzVector<Complex>& quarkRight
= qqbargRightCurrent(2,hel[2],3,hel[3],4,hel[4]);
Complex LL = leptonLeft.dot( quarkLeft );
Complex RL = leptonRight.dot( quarkLeft );
Complex LR = leptonLeft.dot( quarkRight );
Complex RR = leptonRight.dot( quarkRight );
double bProp = (amplitudeMomentum(0)+amplitudeMomentum(1)).m2()/lastSHat();
Complex gamma = 0.0;
if ( includeGamma() )
gamma = Complex(0.,-1.)*(-amplitudePartonData()[2]->iCharge()/3.)*
(LL + RL + LR + RR)/bProp;
bool up = abs(amplitudePartonData()[2]->id()) % 2 == 0;
Complex Z = 0.0;
if ( includeZ() )
Z = Complex(0.,-1.)*
(standardModel()->le()*(up ? standardModel()->lu() : standardModel()->ld())*LL +
standardModel()->re()*(up ? standardModel()->lu() : standardModel()->ld())*RL +
standardModel()->le()*(up ? standardModel()->ru() : standardModel()->rd())*LR +
standardModel()->re()*(up ? standardModel()->ru() : standardModel()->rd())*RR)/
Complex(bProp-sqr(MZ)/lastSHat(),MZ*GZ/lastSHat());
Complex res = 4.*Constants::pi*SM().alphaEMMZ()*sqrt(4.*Constants::pi*SM().alphaS())*(gamma+Z);
largeN = res;
return res;
}
Complex MatchboxAmplitudellbarqqbarg::evaluateOneLoop(size_t, const vector<int>& hel) {
if ( abs(hel[2]+hel[3]) != 2 ) {
return 0.;
}
const LorentzVector<Complex>& leptonLeft
= llbarLeftCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& leptonRight
= llbarRightCurrent(0,hel[0],1,hel[1]);
Complex LL =
hel[2] == 1 ? leptonLeft.dot( qqbargLeftOneLoopCurrent (2,hel[2],3,hel[3],4,hel[4])) : 0.;
Complex RL =
hel[2] == 1 ? leptonRight.dot(qqbargLeftOneLoopCurrent (2,hel[2],3,hel[3],4,hel[4])) : 0.;
Complex LR =
hel[2] == -1 ? leptonLeft.dot( qqbargRightOneLoopCurrent(2,hel[2],3,hel[3],4,hel[4])) : 0.;
Complex RR =
hel[2] == -1 ? leptonRight.dot(qqbargRightOneLoopCurrent(2,hel[2],3,hel[3],4,hel[4])) : 0.;
double bProp = (amplitudeMomentum(0)+amplitudeMomentum(1)).m2()/lastSHat();
Complex gamma = 0.0;
if ( includeGamma() )
gamma = Complex(0.,-1.)*(-amplitudePartonData()[2]->iCharge()/3.)*
(LL + RL + LR + RR)/bProp;
bool up = abs(amplitudePartonData()[2]->id()) % 2 == 0;
Complex Z = 0.0;
if ( includeZ() )
Z = Complex(0.,-1.)*
(standardModel()->le()*(up ? standardModel()->lu() : standardModel()->ld())*LL +
standardModel()->re()*(up ? standardModel()->lu() : standardModel()->ld())*RL +
standardModel()->le()*(up ? standardModel()->ru() : standardModel()->rd())*LR +
standardModel()->re()*(up ? standardModel()->ru() : standardModel()->rd())*RR)/
Complex(bProp-sqr(MZ)/lastSHat(),MZ*GZ/lastSHat());
Complex res =
(SM().alphaS()/(2.*Constants::pi))*
4.*Constants::pi*SM().alphaEMMZ()*sqrt(4.*Constants::pi*SM().alphaS())*(gamma+Z);
return res;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudellbarqqbarg::persistentOutput(PersistentOStream &) const {}
void MatchboxAmplitudellbarqqbarg::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudellbarqqbarg,MatchboxZGammaAmplitude>
describeHerwigMatchboxAmplitudellbarqqbarg("Herwig::MatchboxAmplitudellbarqqbarg", "HwMatchboxBuiltin.so");
void MatchboxAmplitudellbarqqbarg::Init() {
static ClassDocumentation<MatchboxAmplitudellbarqqbarg> documentation
("MatchboxAmplitudellbarqqbarg");
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarg.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarg.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarg.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarg.h
@@ -1,187 +1,179 @@
// -*- C++ -*-
//
// MatchboxAmplitudellbarqqbarg.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudellbarqqbarg_H
#define Herwig_MatchboxAmplitudellbarqqbarg_H
//
// This is the declaration of the MatchboxAmplitudellbarqqbarg class.
//
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxAmplitudellbarqqbarg
*/
class MatchboxAmplitudellbarqqbarg:
public MatchboxZGammaAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudellbarqqbarg();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudellbarqqbarg();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 1; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 2; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return true; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluateOneLoop(size_t, const vector<int>&);
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxZGammaAmplitude::flushCaches();
}
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();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudellbarqqbarg & operator=(const MatchboxAmplitudellbarqqbarg &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudellbarqqbarg_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbargg.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbargg.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbargg.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbargg.cc
@@ -1,224 +1,220 @@
// -*- C++ -*-
//
// MatchboxAmplitudellbarqqbargg.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudellbarqqbargg class.
//
#include "MatchboxAmplitudellbarqqbargg.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudellbarqqbargg::MatchboxAmplitudellbarqqbargg() {}
-MatchboxAmplitudellbarqqbargg::~MatchboxAmplitudellbarqqbargg() {}
-
IBPtr MatchboxAmplitudellbarqqbargg::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudellbarqqbargg::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudellbarqqbargg::doinit() {
MatchboxZGammaAmplitude::doinit();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
nPoints(6);
}
void MatchboxAmplitudellbarqqbargg::doinitrun() {
MatchboxZGammaAmplitude::doinitrun();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
nPoints(6);
}
bool MatchboxAmplitudellbarqqbargg::canHandle(const PDVector& proc) const {
if ( proc.size() != 6 )
return false;
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
PDVector::iterator lepton = xproc.begin();
long leptonId = 0;
for ( ; lepton != xproc.end(); ++lepton )
if ( (**lepton).id() == 11 ||
(**lepton).id() == 13 ||
(**lepton).id() == 15 ) {
break;
}
if ( lepton == xproc.end() )
return false;
leptonId = (**lepton).id();
xproc.erase(lepton);
PDVector::iterator antiLepton = xproc.begin();
for ( ; antiLepton != xproc.end(); ++antiLepton )
if ( (**antiLepton).id() == -leptonId ) {
break;
}
if ( antiLepton == xproc.end() )
return false;
xproc.erase(antiLepton);
PDVector::iterator quark = xproc.begin();
long quarkId = 0;
for ( ; quark != xproc.end(); ++quark )
if ( abs((**quark).id()) < 6 &&
(**quark).id() > 0 &&
(**quark).hardProcessMass() == ZERO ) {
break;
}
if ( quark == xproc.end() )
return false;
quarkId = (**quark).id();
xproc.erase(quark);
PDVector::iterator antiQuark = xproc.begin();
for ( ; antiQuark != xproc.end(); ++antiQuark )
if ( (**antiQuark).id() == -quarkId ) {
break;
}
if ( antiQuark == xproc.end() )
return false;
xproc.erase(antiQuark);
if ( xproc.size() != 2 )
return false;
return xproc[0]->id() == 21 && xproc[1]->id() == 21;
}
void MatchboxAmplitudellbarqqbargg::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxZGammaAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
setupLeptons(0,amplitudeMomentum(0),
1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
momentum(4,amplitudeMomentum(4));
momentum(5,amplitudeMomentum(5));
MatchboxZGammaAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudellbarqqbargg::evaluate(size_t a, const vector<int>& hel, Complex& largeN) {
if ( abs(hel[2]+hel[3]) != 2 ) {
largeN = 0.;
return 0.;
}
const LorentzVector<Complex>& leptonLeft
= llbarLeftCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& leptonRight
= llbarRightCurrent(0,hel[0],1,hel[1]);
assert(amplitudeToColourMap()[2] == 0 &&
amplitudeToColourMap()[3] == 1);
int g1,hg1,g2,hg2;
if ( amplitudeToColourMap()[4] == 2 &&
amplitudeToColourMap()[5] == 3 ) {
if ( a == 0 ) {
g1 = 4; hg1 = hel[4];
g2 = 5; hg2 = hel[5];
} else if ( a == 1 ) {
g1 = 5; hg1 = hel[5];
g2 = 4; hg2 = hel[4];
} else assert(false);
} else if ( amplitudeToColourMap()[4] == 3 &&
amplitudeToColourMap()[5] == 2 ) {
if ( a == 0 ) {
g1 = 5; hg1 = hel[5];
g2 = 4; hg2 = hel[4];
} else if ( a == 1 ) {
g1 = 4; hg1 = hel[4];
g2 = 5; hg2 = hel[5];
} else assert(false);
} else assert(false);
Complex LL =
hel[2] == 1 ? leptonLeft.dot( qqbarggLeftCurrent (2,hel[2],3,hel[3],g1,hg1,g2,hg2)) : 0.;
Complex RL =
hel[2] == 1 ? leptonRight.dot(qqbarggLeftCurrent (2,hel[2],3,hel[3],g1,hg1,g2,hg2)) : 0.;
Complex LR =
hel[2] == -1 ? leptonLeft.dot( qqbarggRightCurrent(2,hel[2],3,hel[3],g1,hg1,g2,hg2)) : 0.;
Complex RR =
hel[2] == -1 ? leptonRight.dot(qqbarggRightCurrent(2,hel[2],3,hel[3],g1,hg1,g2,hg2)) : 0.;
double bProp = (amplitudeMomentum(0)+amplitudeMomentum(1)).m2()/lastSHat();
Complex gamma = 0.0;
if ( includeGamma() )
gamma = Complex(0.,-1.)*(-amplitudePartonData()[2]->iCharge()/3.)*
(LL + RL + LR + RR)/bProp;
bool up = abs(amplitudePartonData()[2]->id()) % 2 == 0;
Complex Z = 0.0;
if ( includeZ() )
Z = Complex(0.,-1.)*
(standardModel()->le()*(up ? standardModel()->lu() : standardModel()->ld())*LL +
standardModel()->re()*(up ? standardModel()->lu() : standardModel()->ld())*RL +
standardModel()->le()*(up ? standardModel()->ru() : standardModel()->rd())*LR +
standardModel()->re()*(up ? standardModel()->ru() : standardModel()->rd())*RR)/
Complex(bProp-sqr(MZ)/lastSHat(),MZ*GZ/lastSHat());
Complex res = sqr(4.*Constants::pi)*SM().alphaEMMZ()*SM().alphaS()*(gamma+Z);
largeN = res;
return res;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudellbarqqbargg::persistentOutput(PersistentOStream &) const {}
void MatchboxAmplitudellbarqqbargg::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudellbarqqbargg,MatchboxZGammaAmplitude>
describeHerwigMatchboxAmplitudellbarqqbargg("Herwig::MatchboxAmplitudellbarqqbargg", "HwMatchboxBuiltin.so");
void MatchboxAmplitudellbarqqbargg::Init() {
static ClassDocumentation<MatchboxAmplitudellbarqqbargg> documentation
("MatchboxAmplitudellbarqqbargg");
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbargg.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbargg.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbargg.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbargg.h
@@ -1,168 +1,160 @@
// -*- C++ -*-
//
// MatchboxAmplitudellbarqqbargg.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudellbarqqbargg_H
#define Herwig_MatchboxAmplitudellbarqqbargg_H
//
// This is the declaration of the MatchboxAmplitudellbarqqbargg class.
//
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxAmplitudellbarqqbargg
*/
class MatchboxAmplitudellbarqqbargg:
public MatchboxZGammaAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudellbarqqbargg();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudellbarqqbargg();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 2; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 2; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxZGammaAmplitude::flushCaches();
}
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();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudellbarqqbargg & operator=(const MatchboxAmplitudellbarqqbargg &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudellbarqqbargg_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarqqbar.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarqqbar.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarqqbar.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarqqbar.cc
@@ -1,377 +1,373 @@
// -*- C++ -*-
//
// MatchboxAmplitudellbarqqbarqqbar.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudellbarqqbarqqbar class.
//
#include "MatchboxAmplitudellbarqqbarqqbar.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudellbarqqbarqqbar::MatchboxAmplitudellbarqqbarqqbar() {}
-MatchboxAmplitudellbarqqbarqqbar::~MatchboxAmplitudellbarqqbarqqbar() {}
-
IBPtr MatchboxAmplitudellbarqqbarqqbar::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudellbarqqbarqqbar::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudellbarqqbarqqbar::doinit() {
MatchboxZGammaAmplitude::doinit();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
nPoints(6);
}
void MatchboxAmplitudellbarqqbarqqbar::doinitrun() {
MatchboxZGammaAmplitude::doinitrun();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
nPoints(6);
}
bool MatchboxAmplitudellbarqqbarqqbar::canHandle(const PDVector& proc) const {
if ( proc.size() != 6 )
return false;
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
PDVector::iterator lepton = xproc.begin();
long leptonId = 0;
for ( ; lepton != xproc.end(); ++lepton )
if ( (**lepton).id() == 11 ||
(**lepton).id() == 13 ||
(**lepton).id() == 15 ) {
break;
}
if ( lepton == xproc.end() )
return false;
leptonId = (**lepton).id();
xproc.erase(lepton);
PDVector::iterator antiLepton = xproc.begin();
for ( ; antiLepton != xproc.end(); ++antiLepton )
if ( (**antiLepton).id() == -leptonId ) {
break;
}
if ( antiLepton == xproc.end() )
return false;
xproc.erase(antiLepton);
PDVector::iterator quark = xproc.begin();
long quarkId = 0;
for ( ; quark != xproc.end(); ++quark )
if ( abs((**quark).id()) < 6 &&
(**quark).id() > 0 &&
(**quark).hardProcessMass() == ZERO ) {
break;
}
if ( quark == xproc.end() )
return false;
quarkId = (**quark).id();
xproc.erase(quark);
PDVector::iterator antiQuark = xproc.begin();
for ( ; antiQuark != xproc.end(); ++antiQuark )
if ( (**antiQuark).id() == -quarkId ) {
break;
}
if ( antiQuark == xproc.end() )
return false;
xproc.erase(antiQuark);
quark = xproc.begin();
quarkId = 0;
for ( ; quark != xproc.end(); ++quark )
if ( abs((**quark).id()) < 6 &&
(**quark).id() > 0 &&
(**quark).hardProcessMass() == ZERO ) {
break;
}
if ( quark == xproc.end() )
return false;
quarkId = (**quark).id();
xproc.erase(quark);
antiQuark = xproc.begin();
for ( ; antiQuark != xproc.end(); ++antiQuark )
if ( (**antiQuark).id() == -quarkId ) {
break;
}
if ( antiQuark == xproc.end() )
return false;
xproc.erase(antiQuark);
return xproc.empty();
}
inline bool leftNonZero(int heli, int helj, int helk, int hell) {
return
heli == 1 && helj == 1 &&
abs(helk+hell) == 2;
}
inline bool rightNonZero(int heli, int helj, int helk, int hell) {
return
heli == -1 && helj == -1 &&
abs(helk+hell) == 2;
}
void MatchboxAmplitudellbarqqbarqqbar::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxZGammaAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
setupLeptons(0,amplitudeMomentum(0),
1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
momentum(4,amplitudeMomentum(4));
momentum(5,amplitudeMomentum(5));
MatchboxZGammaAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudellbarqqbarqqbar::evaluate(size_t a, const vector<int>& hel, Complex& largeN) {
const LorentzVector<Complex>& leptonLeft
= llbarLeftCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& leptonRight
= llbarRightCurrent(0,hel[0],1,hel[1]);
Complex LL2345 =
leftNonZero(hel[2],hel[3],hel[4],hel[5]) &&
abs(amplitudePartonData()[4]->id()) == abs(amplitudePartonData()[5]->id()) ?
leptonLeft.dot(qqbarqqbarLeftCurrent(2,hel[2],3,hel[3],4,hel[4],5,hel[5])) : 0.;
Complex LL4523 =
leftNonZero(hel[4],hel[5],hel[2],hel[3]) &&
abs(amplitudePartonData()[2]->id()) == abs(amplitudePartonData()[3]->id()) ?
leptonLeft.dot(qqbarqqbarLeftCurrent(4,hel[4],5,hel[5],2,hel[2],3,hel[3])) : 0.;
Complex LL2543 =
leftNonZero(hel[2],hel[5],hel[4],hel[3]) &&
abs(amplitudePartonData()[4]->id()) == abs(amplitudePartonData()[3]->id()) ?
-leptonLeft.dot(qqbarqqbarLeftCurrent(2,hel[2],5,hel[5],4,hel[4],3,hel[3])) : 0.;
Complex LL4325 =
leftNonZero(hel[4],hel[3],hel[2],hel[5]) &&
abs(amplitudePartonData()[2]->id()) == abs(amplitudePartonData()[5]->id()) ?
-leptonLeft.dot(qqbarqqbarLeftCurrent(4,hel[4],3,hel[3],2,hel[2],5,hel[5])) : 0.;
Complex LR2345 =
rightNonZero(hel[2],hel[3],hel[4],hel[5]) &&
abs(amplitudePartonData()[4]->id()) == abs(amplitudePartonData()[5]->id()) ?
leptonLeft.dot(qqbarqqbarRightCurrent(2,hel[2],3,hel[3],4,hel[4],5,hel[5])) : 0.;
Complex LR4523 =
rightNonZero(hel[4],hel[5],hel[2],hel[3]) &&
abs(amplitudePartonData()[2]->id()) == abs(amplitudePartonData()[3]->id()) ?
leptonLeft.dot(qqbarqqbarRightCurrent(4,hel[4],5,hel[5],2,hel[2],3,hel[3])) : 0.;
Complex LR2543 =
rightNonZero(hel[2],hel[5],hel[4],hel[3]) &&
abs(amplitudePartonData()[4]->id()) == abs(amplitudePartonData()[3]->id()) ?
-leptonLeft.dot(qqbarqqbarRightCurrent(2,hel[2],5,hel[5],4,hel[4],3,hel[3])) : 0.;
Complex LR4325 =
rightNonZero(hel[4],hel[3],hel[2],hel[5]) &&
abs(amplitudePartonData()[2]->id()) == abs(amplitudePartonData()[5]->id()) ?
-leptonLeft.dot(qqbarqqbarRightCurrent(4,hel[4],3,hel[3],2,hel[2],5,hel[5])) : 0.;
Complex RL2345 =
leftNonZero(hel[2],hel[3],hel[4],hel[5]) &&
abs(amplitudePartonData()[4]->id()) == abs(amplitudePartonData()[5]->id()) ?
leptonRight.dot(qqbarqqbarLeftCurrent(2,hel[2],3,hel[3],4,hel[4],5,hel[5])) : 0.;
Complex RL4523 =
leftNonZero(hel[4],hel[5],hel[2],hel[3]) &&
abs(amplitudePartonData()[2]->id()) == abs(amplitudePartonData()[3]->id()) ?
leptonRight.dot(qqbarqqbarLeftCurrent(4,hel[4],5,hel[5],2,hel[2],3,hel[3])) : 0.;
Complex RL2543 =
leftNonZero(hel[2],hel[5],hel[4],hel[3]) &&
abs(amplitudePartonData()[4]->id()) == abs(amplitudePartonData()[3]->id()) ?
-leptonRight.dot(qqbarqqbarLeftCurrent(2,hel[2],5,hel[5],4,hel[4],3,hel[3])) : 0.;
Complex RL4325 =
leftNonZero(hel[4],hel[3],hel[2],hel[5]) &&
abs(amplitudePartonData()[2]->id()) == abs(amplitudePartonData()[5]->id()) ?
-leptonRight.dot(qqbarqqbarLeftCurrent(4,hel[4],3,hel[3],2,hel[2],5,hel[5])) : 0.;
Complex RR2345 =
rightNonZero(hel[2],hel[3],hel[4],hel[5]) &&
abs(amplitudePartonData()[4]->id()) == abs(amplitudePartonData()[5]->id()) ?
leptonRight.dot(qqbarqqbarRightCurrent(2,hel[2],3,hel[3],4,hel[4],5,hel[5])) : 0.;
Complex RR4523 =
rightNonZero(hel[4],hel[5],hel[2],hel[3]) &&
abs(amplitudePartonData()[2]->id()) == abs(amplitudePartonData()[3]->id()) ?
leptonRight.dot(qqbarqqbarRightCurrent(4,hel[4],5,hel[5],2,hel[2],3,hel[3])) : 0.;
Complex RR2543 =
rightNonZero(hel[2],hel[5],hel[4],hel[3]) &&
abs(amplitudePartonData()[4]->id()) == abs(amplitudePartonData()[3]->id()) ?
-leptonRight.dot(qqbarqqbarRightCurrent(2,hel[2],5,hel[5],4,hel[4],3,hel[3])) : 0.;
Complex RR4325 =
rightNonZero(hel[4],hel[3],hel[2],hel[5]) &&
abs(amplitudePartonData()[2]->id()) == abs(amplitudePartonData()[5]->id()) ?
-leptonRight.dot(qqbarqqbarRightCurrent(4,hel[4],3,hel[3],2,hel[2],5,hel[5])) : 0.;
double bProp = (amplitudeMomentum(0)+amplitudeMomentum(1)).m2()/lastSHat();
Complex gamma2345 =
Complex(0.,-1.)*(-amplitudePartonData()[2]->iCharge()/3.)*
(LL2345 + RL2345 + LR2345 + RR2345)/bProp;
Complex gamma2543 =
Complex(0.,-1.)*(-amplitudePartonData()[2]->iCharge()/3.)*
(LL2543 + RL2543 + LR2543 + RR2543)/bProp;
Complex gamma4523 =
Complex(0.,-1.)*(-amplitudePartonData()[4]->iCharge()/3.)*
(LL4523 + RL4523 + LR4523 + RR4523)/bProp;
Complex gamma4325 =
Complex(0.,-1.)*(-amplitudePartonData()[4]->iCharge()/3.)*
(LL4325 + RL4325 + LR4325 + RR4325)/bProp;
bool up2 = abs(amplitudePartonData()[2]->id()) % 2 == 0;
bool up4 = abs(amplitudePartonData()[4]->id()) % 2 == 0;
Complex Z2345 =
Complex(0.,-1.)*
(standardModel()->le()*(up2 ? standardModel()->lu() : standardModel()->ld())*LL2345 +
standardModel()->re()*(up2 ? standardModel()->lu() : standardModel()->ld())*RL2345 +
standardModel()->le()*(up2 ? standardModel()->ru() : standardModel()->rd())*LR2345 +
standardModel()->re()*(up2 ? standardModel()->ru() : standardModel()->rd())*RR2345)/
Complex(bProp-sqr(MZ)/lastSHat(),MZ*GZ/lastSHat());
Complex Z2543 =
Complex(0.,-1.)*
(standardModel()->le()*(up2 ? standardModel()->lu() : standardModel()->ld())*LL2543 +
standardModel()->re()*(up2 ? standardModel()->lu() : standardModel()->ld())*RL2543 +
standardModel()->le()*(up2 ? standardModel()->ru() : standardModel()->rd())*LR2543 +
standardModel()->re()*(up2 ? standardModel()->ru() : standardModel()->rd())*RR2543)/
Complex(bProp-sqr(MZ)/lastSHat(),MZ*GZ/lastSHat());
Complex Z4523 =
Complex(0.,-1.)*
(standardModel()->le()*(up4 ? standardModel()->lu() : standardModel()->ld())*LL4523 +
standardModel()->re()*(up4 ? standardModel()->lu() : standardModel()->ld())*RL4523 +
standardModel()->le()*(up4 ? standardModel()->ru() : standardModel()->rd())*LR4523 +
standardModel()->re()*(up4 ? standardModel()->ru() : standardModel()->rd())*RR4523)/
Complex(bProp-sqr(MZ)/lastSHat(),MZ*GZ/lastSHat());
Complex Z4325 =
Complex(0.,-1.)*
(standardModel()->le()*(up4 ? standardModel()->lu() : standardModel()->ld())*LL4325 +
standardModel()->re()*(up4 ? standardModel()->lu() : standardModel()->ld())*RL4325 +
standardModel()->le()*(up4 ? standardModel()->ru() : standardModel()->rd())*LR4325 +
standardModel()->re()*(up4 ? standardModel()->ru() : standardModel()->rd())*RR4325)/
Complex(bProp-sqr(MZ)/lastSHat(),MZ*GZ/lastSHat());
Complex sum2345 = 0.0;
Complex sum2543 = 0.0;
Complex sum4523 = 0.0;
Complex sum4325 = 0.0;
if ( includeGamma() ) {
sum2345 += sqr(4.*Constants::pi)*SM().alphaEMMZ()*SM().alphaS()*gamma2345;
sum2543 += sqr(4.*Constants::pi)*SM().alphaEMMZ()*SM().alphaS()*gamma2543;
sum4523 += sqr(4.*Constants::pi)*SM().alphaEMMZ()*SM().alphaS()*gamma4523;
sum4325 += sqr(4.*Constants::pi)*SM().alphaEMMZ()*SM().alphaS()*gamma4325;
}
if ( includeZ() ) {
sum2345 += sqr(4.*Constants::pi)*SM().alphaEMMZ()*SM().alphaS()*Z2345;
sum2543 += sqr(4.*Constants::pi)*SM().alphaEMMZ()*SM().alphaS()*Z2543;
sum4523 += sqr(4.*Constants::pi)*SM().alphaEMMZ()*SM().alphaS()*Z4523;
sum4325 += sqr(4.*Constants::pi)*SM().alphaEMMZ()*SM().alphaS()*Z4325;
}
double Nc = SM().Nc();
Complex resLeading = 0.;
Complex resSubLeading = 0.;
if ( amplitudeToColourMap()[2] == 0 && amplitudeToColourMap()[3] == 1 &&
amplitudeToColourMap()[4] == 2 && amplitudeToColourMap()[5] == 3 ) {
if ( a == 0 ) { //(23)(45)
resLeading = sum2543 + sum4325;
resSubLeading = sum2345 + sum4523;
} else if ( a == 1 ) { //(25)(43)
resLeading = sum2345 + sum4523;
resSubLeading = sum2543 + sum4325;
} else assert(false);
} else if ( amplitudeToColourMap()[2] == 0 && amplitudeToColourMap()[3] == 3 &&
amplitudeToColourMap()[4] == 2 && amplitudeToColourMap()[5] == 1 ) {
if ( a == 0 ) { // (25)(43)
resLeading = sum2345 + sum4523;
resSubLeading = sum2543 + sum4325;
} else if ( a == 1 ) { // (23)(45)
resLeading = sum2543 + sum4325;
resSubLeading = sum2345 + sum4523;
} else assert(false);
} else if ( amplitudeToColourMap()[2] == 2 && amplitudeToColourMap()[3] == 3 &&
amplitudeToColourMap()[4] == 0 && amplitudeToColourMap()[5] == 1 ) {
if ( a == 0 ) { //(23)(45)
resLeading = sum2543 + sum4325;
resSubLeading = sum2345 + sum4523;
} else if ( a == 1 ) { //(25)(43)
resLeading = sum2345 + sum4523;
resSubLeading = sum2543 + sum4325;
} else assert(false);
} else if ( amplitudeToColourMap()[2] == 2 && amplitudeToColourMap()[3] == 1 &&
amplitudeToColourMap()[4] == 0 && amplitudeToColourMap()[5] == 3 ) {
if ( a == 0 ) { //(25)(43)
resLeading = sum2345 + sum4523;
resSubLeading = sum2543 + sum4325;
} else if ( a == 1 ) { //(23)(45)
resLeading = sum2543 + sum4325;
resSubLeading = sum2345 + sum4523;
} else assert(false);
} else assert(false);
resSubLeading *= -1./Nc;
largeN = resLeading/2.;
return (resLeading + resSubLeading)/2.;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudellbarqqbarqqbar::persistentOutput(PersistentOStream &) const {}
void MatchboxAmplitudellbarqqbarqqbar::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudellbarqqbarqqbar,MatchboxZGammaAmplitude>
describeHerwigMatchboxAmplitudellbarqqbarqqbar("Herwig::MatchboxAmplitudellbarqqbarqqbar", "HwMatchboxBuiltin.so");
void MatchboxAmplitudellbarqqbarqqbar::Init() {
static ClassDocumentation<MatchboxAmplitudellbarqqbarqqbar> documentation
("MatchboxAmplitudellbarqqbarqqbar");
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarqqbar.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarqqbar.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarqqbar.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudellbarqqbarqqbar.h
@@ -1,168 +1,160 @@
// -*- C++ -*-
//
// MatchboxAmplitudellbarqqbarqqbar.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudellbarqqbarqqbar_H
#define Herwig_MatchboxAmplitudellbarqqbarqqbar_H
//
// This is the declaration of the MatchboxAmplitudellbarqqbarqqbar class.
//
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxAmplitudellbarqqbarqqbar
*/
class MatchboxAmplitudellbarqqbarqqbar:
public MatchboxZGammaAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudellbarqqbarqqbar();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudellbarqqbarqqbar();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 2; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 2; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxZGammaAmplitude::flushCaches();
}
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();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudellbarqqbarqqbar & operator=(const MatchboxAmplitudellbarqqbarqqbar &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudellbarqqbarqqbar_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbar.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbar.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbar.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbar.cc
@@ -1,192 +1,190 @@
// -*- C++ -*-
//
// MatchboxAmplitudelnuqqbar.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudelnuqqbar class.
//
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbar.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
using namespace Herwig;
MatchboxAmplitudelnuqqbar::MatchboxAmplitudelnuqqbar()
- : theDiagonal(false) {}
-
-MatchboxAmplitudelnuqqbar::~MatchboxAmplitudelnuqqbar() {}
+ : theDiagonal(false) {}
void MatchboxAmplitudelnuqqbar::doinit() {
MatchboxAmplitude::doinit();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
theCKM = standardCKM(SM())->getUnsquaredMatrix(6);
nPoints(4);
}
void MatchboxAmplitudelnuqqbar::doinitrun() {
MatchboxAmplitude::doinitrun();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
nPoints(4);
}
IBPtr MatchboxAmplitudelnuqqbar::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudelnuqqbar::fullclone() const {
return new_ptr(*this);
}
bool MatchboxAmplitudelnuqqbar::canHandle(const PDVector& proc) const {
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
PDVector::iterator elektron = xproc.begin();
for ( ; elektron != xproc.end(); ++elektron )
if ( abs((*elektron)->id()) >= 11 && abs((*elektron)->id()) <= 16 && abs((*elektron)->id()) % 2 == 1 ) break;
if ( elektron == xproc.end() ) return false;
PDPtr e = *elektron;
xproc.erase(elektron);
PDVector::iterator neutrino = xproc.begin();
for ( ; neutrino != xproc.end(); ++neutrino )
if ( abs((*neutrino)->id()) >= 11 && abs((*neutrino)->id()) <= 16 && abs((*neutrino)->id()) % 2 == 0 ) break;
if ( neutrino == xproc.end() ) return false;
PDPtr n = *neutrino;
xproc.erase(neutrino);
PDVector::iterator quark = xproc.begin();
for ( ; quark != xproc.end(); ++quark )
if ( abs((*quark)->id()) >= 1 && abs((*quark)->id()) <= 6 && abs((*quark)->id()) % 2 == 1 ) {
assert( (*quark)->hardProcessMass() == ZERO );
break;
}
if ( quark == xproc.end() ) return false;
PDPtr d = *quark;
xproc.erase(quark);
quark = xproc.begin();
for ( ; quark != xproc.end(); ++quark )
if ( abs((*quark)->id()) >= 1 && abs((*quark)->id()) <= 6 && abs((*quark)->id()) % 2 == 0 ) {
assert( (*quark)->hardProcessMass() == ZERO );
break;
}
if ( quark == xproc.end() ) return false;
PDPtr u = *quark;
xproc.erase(quark);
if ( u->iCharge() + d->iCharge() + e->iCharge() != PDT::ChargeNeutral ) return false;
if ( theDiagonal && SU2Helper::family(u) != SU2Helper::family(d) ) return false;
if ( SU2Helper::family(e) != SU2Helper::family(n) ) return false;
return xproc.empty();
}
void MatchboxAmplitudelnuqqbar::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
setupLeptons(0,amplitudeMomentum(0),1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudelnuqqbar::evaluate(size_t, const vector<int>& hel, Complex& largeN) {
if ( abs(hel[2]+hel[3]) != 2 ) {
largeN = 0.;
return 0.;
}
Complex ckmelement = 1.;
if ( !theDiagonal ) {
bool wPlus = ( abs(amplitudePartonData()[0]->id()) % 2 == 0 ) ?
amplitudePartonData()[1]->id() < 0:
amplitudePartonData()[0]->id() < 0;
pair<int,int> tmp(
SU2Helper::family(amplitudePartonData()[2])-1,
SU2Helper::family(amplitudePartonData()[3])-1);
if ( amplitudePartonData()[3]->id() < 0 ) swap(tmp.first,tmp.second);
ckmelement = theCKM[tmp.first][tmp.second];
if ( !wPlus ) ckmelement = conj(ckmelement);
}
Complex wPropergator =
1./Complex(((amplitudeMomentum(0)+amplitudeMomentum(1)).m2()-sqr(MW))/lastSHat(),MW*GW/lastSHat());
Complex wVertices =
2.*SM().alphaEMMZ()*Constants::pi/SM().sin2ThetaW()*ckmelement;
const LorentzVector<Complex>& leptonCurrent = llbarLeftCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& quarkCurrent = qqbarLeftCurrent(2,hel[2],3,hel[3]);
Complex current = hel[2] == 1 ? Complex(0.,-1)*leptonCurrent.dot(quarkCurrent): 0.;
Complex res = current*wVertices*wPropergator;
largeN = res;
return res;
}
Complex MatchboxAmplitudelnuqqbar::evaluateOneLoop(size_t, const vector<int>& hel) {
if ( abs(hel[2]+hel[3]) != 2 ) return 0.;
Complex ckmelement = 1.;
if ( !theDiagonal ) {
bool wPlus = ( abs(amplitudePartonData()[0]->id()) % 2 == 0 ) ?
amplitudePartonData()[1]->id() < 0:
amplitudePartonData()[0]->id() < 0;
pair<int,int> tmp(
SU2Helper::family(amplitudePartonData()[2])-1,
SU2Helper::family(amplitudePartonData()[3])-1);
if ( amplitudePartonData()[3]->id() < 0 ) swap(tmp.first,tmp.second);
ckmelement = theCKM[tmp.first][tmp.second];
if ( !wPlus ) ckmelement = conj(ckmelement);
}
Complex wPropergator =
1./Complex(((amplitudeMomentum(0)+amplitudeMomentum(1)).m2()-sqr(MW))/lastSHat(),MW*GW/lastSHat());
Complex wVertices =
2.*SM().alphaEMMZ()*Constants::pi/SM().sin2ThetaW()*ckmelement;
const LorentzVector<Complex>& leptonCurrent = llbarLeftCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& quarkCurrent = qqbarLeftOneLoopCurrent(2,hel[2],3,hel[3]);
Complex current = hel[2] == 1 ? Complex(0.,-1)*leptonCurrent.dot(quarkCurrent): 0.;
Complex res = (SM().alphaS()/(2.*Constants::pi))*current*wVertices*wPropergator;
return res;
}
void MatchboxAmplitudelnuqqbar::persistentOutput(PersistentOStream & os) const {
os << theDiagonal << theCKM ;
}
void MatchboxAmplitudelnuqqbar::persistentInput(PersistentIStream & is, int) {
is >> theDiagonal >> theCKM ;
}
DescribeClass<MatchboxAmplitudelnuqqbar,MatchboxAmplitude>
describeHerwigMatchboxAmplitudelnuqqbar("Herwig::MatchboxAmplitudelnuqqbar", "HwMatchboxBuiltin.so");
void MatchboxAmplitudelnuqqbar::Init() {
static ClassDocumentation<MatchboxAmplitudelnuqqbar> documentation
("MatchboxAmplitudelnuqqbar");
static Switch<MatchboxAmplitudelnuqqbar,bool> interfaceDiagonal
("Diagonal",
"Use a diagonal CKM matrix (ignoring the CKM object of the StandardModel).",
&MatchboxAmplitudelnuqqbar::theDiagonal, false, false, false);
static SwitchOption interfaceDiagonalYes
(interfaceDiagonal,
"Yes",
"Use a diagonal CKM matrix.",
true);
static SwitchOption interfaceDiagonalNo
(interfaceDiagonal,
"No",
"Use the CKM object as used by the StandardModel.",
false);
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbar.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbar.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbar.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbar.h
@@ -1,185 +1,180 @@
// -*- C++ -*-
//
// MatchboxAmplitudelnuqqbar.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudelnuqqbar_H
#define Herwig_MatchboxAmplitudelnuqqbar_H
//
// This is the declaration of the MatchboxAmplitudelnuqqbar class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SU2Helper.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Thomas Schuh
*
* \brief MatchboxAmplitudelnuqqbar
*/
class MatchboxAmplitudelnuqqbar: public MatchboxAmplitude, public MatchboxCurrents {
public:
/**
* The default constructor.
*/
MatchboxAmplitudelnuqqbar();
/**
- * The destructor.
- */
- virtual ~MatchboxAmplitudelnuqqbar();
-
- /**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 0; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 2; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return true; }
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluateOneLoop(size_t, const vector<int>&);
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
/**
* 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:
/**
* 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;
/**
* 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:
/**
* True, if a diagonal CKM matrix should be assumed. This ignores
* the CKM object of the StandardModel.
*/
bool theDiagonal;
/**
* The ckm.
*/
vector< vector<Complex> > theCKM;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudelnuqqbar & operator=(const MatchboxAmplitudelnuqqbar &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudelnuqqbar_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarg.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarg.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarg.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarg.cc
@@ -1,203 +1,201 @@
// -*- C++ -*-
//
// MatchboxAmplitudelnuqqbarg.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudelnuqqbarg class.
//
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarg.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
using namespace Herwig;
MatchboxAmplitudelnuqqbarg::MatchboxAmplitudelnuqqbarg()
- : theDiagonal(false) {}
-
-MatchboxAmplitudelnuqqbarg::~MatchboxAmplitudelnuqqbarg() {}
+ : theDiagonal(false) {}
void MatchboxAmplitudelnuqqbarg::doinit() {
MatchboxAmplitude::doinit();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
theCKM = standardCKM(SM())->getUnsquaredMatrix(6);
nPoints(5);
}
void MatchboxAmplitudelnuqqbarg::doinitrun() {
MatchboxAmplitude::doinitrun();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
nPoints(5);
}
IBPtr MatchboxAmplitudelnuqqbarg::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudelnuqqbarg::fullclone() const {
return new_ptr(*this);
}
bool MatchboxAmplitudelnuqqbarg::canHandle(const PDVector& proc) const {
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
PDVector::iterator elektron = xproc.begin();
for ( ; elektron != xproc.end(); ++elektron )
if ( abs((*elektron)->id()) >= 11 && abs((*elektron)->id()) <= 16 && abs((*elektron)->id()) % 2 == 1 ) break;
if ( elektron == xproc.end() ) return false;
PDPtr e = *elektron;
xproc.erase(elektron);
PDVector::iterator neutrino = xproc.begin();
for ( ; neutrino != xproc.end(); ++neutrino )
if ( abs((*neutrino)->id()) >= 11 && abs((*neutrino)->id()) <= 16 && abs((*neutrino)->id()) % 2 == 0 ) break;
if ( neutrino == xproc.end() ) return false;
PDPtr n = *neutrino;
xproc.erase(neutrino);
PDVector::iterator quark = xproc.begin();
for ( ; quark != xproc.end(); ++quark )
if ( abs((*quark)->id()) >= 1 && abs((*quark)->id()) <= 6 && abs((*quark)->id()) % 2 == 1 ) {
assert( (*quark)->hardProcessMass() == ZERO );
break;
}
if ( quark == xproc.end() ) return false;
PDPtr d = *quark;
xproc.erase(quark);
quark = xproc.begin();
for ( ; quark != xproc.end(); ++quark )
if ( abs((*quark)->id()) >= 1 && abs((*quark)->id()) <= 6 && abs((*quark)->id()) % 2 == 0 ) {
assert( (*quark)->hardProcessMass() == ZERO );
break;
}
if ( quark == xproc.end() ) return false;
PDPtr u = *quark;
xproc.erase(quark);
PDVector::iterator gluon = xproc.begin();
for ( ; gluon != xproc.end(); ++gluon )
if ( (*gluon)->id() == 21 ) break;
if ( gluon == xproc.end() ) return false;
xproc.erase(gluon);
if ( SU2Helper::family(e) != SU2Helper::family(n) ) return false;
if ( u->iCharge() + d->iCharge() + e->iCharge() != PDT::ChargeNeutral ) return false;
if ( theDiagonal && SU2Helper::family(u) != SU2Helper::family(d) ) return false;
return xproc.empty();
}
void MatchboxAmplitudelnuqqbarg::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
setupLeptons(0,amplitudeMomentum(0),1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
momentum(4,amplitudeMomentum(4));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudelnuqqbarg::evaluate(size_t, const vector<int>& hel, Complex& largeN) {
if ( abs(hel[2]+hel[3]) != 2 ) {
largeN = 0.;
return 0.;
}
Complex ckmelement = 1.;
if ( !theDiagonal ) {
bool wPlus = ( abs(amplitudePartonData()[0]->id()) % 2 == 0 ) ?
amplitudePartonData()[1]->id() < 0:
amplitudePartonData()[0]->id() < 0;
pair<int,int> tmp(
SU2Helper::family(amplitudePartonData()[2])-1,
SU2Helper::family(amplitudePartonData()[3])-1);
if ( amplitudePartonData()[3]->id() < 0 ) swap(tmp.first,tmp.second);
ckmelement = theCKM[tmp.first][tmp.second];
if ( !wPlus ) ckmelement = conj(ckmelement);
}
Complex wPropergator =
1./Complex(((amplitudeMomentum(0)+amplitudeMomentum(1)).m2()-sqr(MW))/lastSHat(),MW*GW/lastSHat());
Complex wVertices =
2.*SM().alphaEMMZ()*Constants::pi/SM().sin2ThetaW()*ckmelement;
Complex sVertex =
sqrt(4.*Constants::pi*SM().alphaS());
const LorentzVector<Complex>& leptonCurrent = llbarLeftCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& quarkCurrent = qqbargLeftCurrent(2,hel[2],3,hel[3],4,hel[4]);
Complex current = hel[2] == 1 ? Complex(0.,-1)*leptonCurrent.dot(quarkCurrent): 0.;
Complex res = current*wVertices*wPropergator*sVertex;
largeN = res;
return res;
}
Complex MatchboxAmplitudelnuqqbarg::evaluateOneLoop(size_t, const vector<int>& hel) {
if ( abs(hel[2]+hel[3]) != 2 ) return 0.;
Complex ckmelement = 1.;
if ( !theDiagonal ) {
bool wPlus = ( abs(amplitudePartonData()[0]->id()) % 2 == 0 ) ?
amplitudePartonData()[1]->id() < 0:
amplitudePartonData()[0]->id() < 0;
pair<int,int> tmp(
SU2Helper::family(amplitudePartonData()[2])-1,
SU2Helper::family(amplitudePartonData()[3])-1);
if ( amplitudePartonData()[3]->id() < 0 ) swap(tmp.first,tmp.second);
ckmelement = theCKM[tmp.first][tmp.second];
if ( !wPlus ) ckmelement = conj(ckmelement);
}
Complex wPropergator =
1./Complex(((amplitudeMomentum(0)+amplitudeMomentum(1)).m2()-sqr(MW))/lastSHat(),MW*GW/lastSHat());
Complex wVertices =
2.*SM().alphaEMMZ()*Constants::pi/SM().sin2ThetaW()*ckmelement;
Complex sVertex =
sqrt(4.*Constants::pi*SM().alphaS());
const LorentzVector<Complex>& leptonCurrent = llbarLeftCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& quarkCurrent = qqbargLeftOneLoopCurrent(2,hel[2],3,hel[3],4,hel[4]);
Complex current = hel[2] == 1 ? Complex(0.,-1)*leptonCurrent.dot(quarkCurrent): 0.;
Complex res = (SM().alphaS()/(2.*Constants::pi))*current*wVertices*wPropergator*sVertex;
return res;
}
void MatchboxAmplitudelnuqqbarg::persistentOutput(PersistentOStream & os) const {
os << theDiagonal << theCKM ;
}
void MatchboxAmplitudelnuqqbarg::persistentInput(PersistentIStream & is, int) {
is >> theDiagonal >> theCKM ;
}
DescribeClass<MatchboxAmplitudelnuqqbarg,MatchboxAmplitude>
describeHerwigMatchboxAmplitudelnuqqbarg("Herwig::MatchboxAmplitudelnuqqbarg", "HwMatchboxBuiltin.so");
void MatchboxAmplitudelnuqqbarg::Init() {
static ClassDocumentation<MatchboxAmplitudelnuqqbarg> documentation
("MatchboxAmplitudelnuqqbarg");
static Switch<MatchboxAmplitudelnuqqbarg,bool> interfaceDiagonal
("Diagonal",
"Use a diagonal CKM matrix (ignoring the CKM object of the StandardModel).",
&MatchboxAmplitudelnuqqbarg::theDiagonal, false, false, false);
static SwitchOption interfaceDiagonalYes
(interfaceDiagonal,
"Yes",
"Use a diagonal CKM matrix.",
true);
static SwitchOption interfaceDiagonalNo
(interfaceDiagonal,
"No",
"Use the CKM object as used by the StandardModel.",
false);
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarg.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarg.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarg.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarg.h
@@ -1,185 +1,180 @@
// -*- C++ -*-
//
// MatchboxAmplitudelnuqqbarg.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudelnuqqbarg_H
#define Herwig_MatchboxAmplitudelnuqqbarg_H
//
// This is the declaration of the MatchboxAmplitudelnuqqbarg class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SU2Helper.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Thomas Schuh
*
* \brief MatchboxAmplitudelnuqqbarg
*/
class MatchboxAmplitudelnuqqbarg: public MatchboxAmplitude, public MatchboxCurrents {
public:
/**
* The default constructor.
*/
MatchboxAmplitudelnuqqbarg();
/**
- * The destructor.
- */
- virtual ~MatchboxAmplitudelnuqqbarg();
-
- /**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 1; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 2; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return true; }
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluateOneLoop(size_t, const vector<int>&);
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
/**
* 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:
/**
* 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;
/**
* 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:
/**
* True, if a diagonal CKM matrix should be assumed. This ignores
* the CKM object of the StandardModel.
*/
bool theDiagonal;
/**
* The ckm.
*/
vector< vector<Complex> > theCKM;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudelnuqqbarg & operator=(const MatchboxAmplitudelnuqqbarg &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudelnuqqbarg_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbargg.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbargg.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbargg.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbargg.cc
@@ -1,201 +1,199 @@
// -*- C++ -*-
//
// MatchboxAmplitudelnuqqbargg.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudelnuqqbargg class.
//
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbargg.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
using namespace Herwig;
MatchboxAmplitudelnuqqbargg::MatchboxAmplitudelnuqqbargg()
- : theDiagonal(false) {}
-
-MatchboxAmplitudelnuqqbargg::~MatchboxAmplitudelnuqqbargg() {}
+ : theDiagonal(false) {}
void MatchboxAmplitudelnuqqbargg::doinit() {
MatchboxAmplitude::doinit();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
theCKM = standardCKM(SM())->getUnsquaredMatrix(6);
nPoints(6);
}
void MatchboxAmplitudelnuqqbargg::doinitrun() {
MatchboxAmplitude::doinitrun();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
nPoints(6);
}
IBPtr MatchboxAmplitudelnuqqbargg::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudelnuqqbargg::fullclone() const {
return new_ptr(*this);
}
bool MatchboxAmplitudelnuqqbargg::canHandle(const PDVector& proc) const {
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
PDVector::iterator elektron = xproc.begin();
for ( ; elektron != xproc.end(); ++elektron )
if ( abs((*elektron)->id()) >= 11 && abs((*elektron)->id()) <= 16 && abs((*elektron)->id()) % 2 == 1 ) break;
if ( elektron == xproc.end() ) return false;
PDPtr e = *elektron;
xproc.erase(elektron);
PDVector::iterator neutrino = xproc.begin();
for ( ; neutrino != xproc.end(); ++neutrino )
if ( abs((*neutrino)->id()) >= 11 && abs((*neutrino)->id()) <= 16 && abs((*neutrino)->id()) % 2 == 0 ) break;
if ( neutrino == xproc.end() ) return false;
PDPtr n = *neutrino;
xproc.erase(neutrino);
PDVector::iterator quark = xproc.begin();
for ( ; quark != xproc.end(); ++quark )
if ( abs((*quark)->id()) >= 1 && abs((*quark)->id()) <= 6 && abs((*quark)->id()) % 2 == 1 ) {
assert( (*quark)->hardProcessMass() == ZERO );
break;
}
if ( quark == xproc.end() ) return false;
PDPtr d = *quark;
xproc.erase(quark);
quark = xproc.begin();
for ( ; quark != xproc.end(); ++quark )
if ( abs((*quark)->id()) >= 1 && abs((*quark)->id()) <= 6 && abs((*quark)->id()) % 2 == 0 ) {
assert( (*quark)->hardProcessMass() == ZERO );
break;
}
if ( quark == xproc.end() ) return false;
PDPtr u = *quark;
xproc.erase(quark);
PDVector::iterator gluon = xproc.begin();
for ( ; gluon != xproc.end(); ++gluon )
if ( (*gluon)->id() == 21 ) break;
if ( gluon == xproc.end() ) return false;
xproc.erase(gluon);
gluon = xproc.begin();
for ( ; gluon != xproc.end(); ++gluon )
if ( (*gluon)->id() == 21 ) break;
if ( gluon == xproc.end() ) return false;
xproc.erase(gluon);
if ( SU2Helper::family(e) != SU2Helper::family(n) ) return false;
if ( u->iCharge() + d->iCharge() + e->iCharge() != PDT::ChargeNeutral ) return false;
if ( theDiagonal && SU2Helper::family(u) != SU2Helper::family(d) ) return false;
return xproc.empty();
}
void MatchboxAmplitudelnuqqbargg::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
setupLeptons(0,amplitudeMomentum(0),1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
momentum(4,amplitudeMomentum(4));
momentum(5,amplitudeMomentum(5));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudelnuqqbargg::evaluate(size_t a, const vector<int>& hel, Complex& largeN) {
if ( abs(hel[2]+hel[3]) != 2 ) {
largeN = 0.;
return 0.;
}
assert ( amplitudeToColourMap()[2] == 0 && amplitudeToColourMap()[3] == 1 );
int g1,hg1,g2,hg2;
if ( amplitudeToColourMap()[4] == 2 && amplitudeToColourMap()[5] == 3 ) {
if ( a == 0 ) {
g1 = 4; hg1 = hel[4];
g2 = 5; hg2 = hel[5];
} else if ( a == 1 ) {
g1 = 5; hg1 = hel[5];
g2 = 4; hg2 = hel[4];
} else assert ( false );
} else if ( amplitudeToColourMap()[4] == 3 && amplitudeToColourMap()[5] == 2 ) {
if ( a == 0 ) {
g1 = 5; hg1 = hel[5];
g2 = 4; hg2 = hel[4];
} else if ( a == 1 ) {
g1 = 4; hg1 = hel[4];
g2 = 5; hg2 = hel[5];
} else assert ( false );
} else assert ( false );
Complex ckmelement = 1.;
if ( !theDiagonal ) {
bool wPlus = ( abs(amplitudePartonData()[0]->id()) % 2 == 0 ) ?
amplitudePartonData()[1]->id() < 0:
amplitudePartonData()[0]->id() < 0;
pair<int,int> tmp(
SU2Helper::family(amplitudePartonData()[2]),
SU2Helper::family(amplitudePartonData()[3]));
if ( amplitudePartonData()[3]->id() < 0 ) swap(tmp.first,tmp.second);
ckmelement = theCKM[tmp.first][tmp.second];
if ( !wPlus ) ckmelement = conj(ckmelement);
}
Complex wPropergator =
1./Complex(((amplitudeMomentum(0)+amplitudeMomentum(1)).m2()-sqr(MW))/lastSHat(),MW*GW/lastSHat());
Complex wVertices =
2.*SM().alphaEMMZ()*Constants::pi/SM().sin2ThetaW()*ckmelement;
Complex sVertices =
4.*Constants::pi*SM().alphaS();
const LorentzVector<Complex>& leptonCurrent = llbarLeftCurrent(0,hel[0],1,hel[1]);
const LorentzVector<Complex>& quarkCurrent = qqbarggLeftCurrent(2,hel[2],3,hel[3],g1,hg1,g2,hg2);
Complex current = hel[2] == 1 ? Complex(0.,-1)*leptonCurrent.dot(quarkCurrent): 0.;
Complex res = current*wVertices*wPropergator*sVertices;
largeN = res;
return res;
}
void MatchboxAmplitudelnuqqbargg::persistentOutput(PersistentOStream & os) const {
os << theDiagonal << theCKM ;
}
void MatchboxAmplitudelnuqqbargg::persistentInput(PersistentIStream & is, int) {
is >> theDiagonal >> theCKM ;
}
DescribeClass<MatchboxAmplitudelnuqqbargg,MatchboxAmplitude>
describeHerwigMatchboxAmplitudelnuqqbargg("Herwig::MatchboxAmplitudelnuqqbargg", "HwMatchboxBuiltin.so");
void MatchboxAmplitudelnuqqbargg::Init() {
static ClassDocumentation<MatchboxAmplitudelnuqqbargg> documentation
("MatchboxAmplitudelnuqqbargg");
static Switch<MatchboxAmplitudelnuqqbargg,bool> interfaceDiagonal
("Diagonal",
"Use a diagonal CKM matrix (ignoring the CKM object of the StandardModel).",
&MatchboxAmplitudelnuqqbargg::theDiagonal, false, false, false);
static SwitchOption interfaceDiagonalYes
(interfaceDiagonal,
"Yes",
"Use a diagonal CKM matrix.",
true);
static SwitchOption interfaceDiagonalNo
(interfaceDiagonal,
"No",
"Use the CKM object as used by the StandardModel.",
false);
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbargg.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbargg.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbargg.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbargg.h
@@ -1,179 +1,174 @@
// -*- C++ -*-
//
// MatchboxAmplitudelnuqqbargg.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudelnuqqbargg_H
#define Herwig_MatchboxAmplitudelnuqqbargg_H
//
// This is the declaration of the MatchboxAmplitudelnuqqbargg class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SU2Helper.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Thomas Schuh
*
* \brief MatchboxAmplitudelnuqqbargg
*/
class MatchboxAmplitudelnuqqbargg: public MatchboxAmplitude, public MatchboxCurrents {
public:
/**
* The default constructor.
*/
MatchboxAmplitudelnuqqbargg();
/**
- * The destructor.
- */
- virtual ~MatchboxAmplitudelnuqqbargg();
-
- /**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 2; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 2; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
/**
* 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:
/**
* 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;
/**
* 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:
/**
* True, if a diagonal CKM matrix should be assumed. This ignores
* the CKM object of the StandardModel.
*/
bool theDiagonal;
/**
* The ckm.
*/
vector< vector<Complex> > theCKM;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudelnuqqbargg & operator=(const MatchboxAmplitudelnuqqbargg &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudelnuqqbargg_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarqqbar.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarqqbar.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarqqbar.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarqqbar.cc
@@ -1,275 +1,273 @@
// -*- C++ -*-
//
// MatchboxAmplitudelnuqqbarqqbar.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudelnuqqbarqqbar class.
//
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarqqbar.h"
using namespace Herwig;
MatchboxAmplitudelnuqqbarqqbar::MatchboxAmplitudelnuqqbarqqbar()
- : theDiagonal(false) {}
-
-MatchboxAmplitudelnuqqbarqqbar::~MatchboxAmplitudelnuqqbarqqbar() {}
+ : theDiagonal(false) {}
void MatchboxAmplitudelnuqqbarqqbar::doinit() {
MatchboxAmplitude::doinit();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
theCKM = standardCKM(SM())->getUnsquaredMatrix(6);
nPoints(6);
}
void MatchboxAmplitudelnuqqbarqqbar::doinitrun() {
MatchboxAmplitude::doinitrun();
MZ = getParticleData(ParticleID::Z0)->hardProcessMass();
GZ = getParticleData(ParticleID::Z0)->hardProcessWidth();
MW = getParticleData(ParticleID::Wplus)->hardProcessMass();
GW = getParticleData(ParticleID::Wplus)->hardProcessWidth();
CA = SM().Nc();
CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
nPoints(6);
}
IBPtr MatchboxAmplitudelnuqqbarqqbar::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudelnuqqbarqqbar::fullclone() const {
return new_ptr(*this);
}
bool MatchboxAmplitudelnuqqbarqqbar::canHandle(const PDVector& proc) const {
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
// Charge charge(ZERO);
PDVector::iterator elektron = xproc.begin();
for ( ; elektron != xproc.end(); ++elektron )
if ( abs((*elektron)->id()) >= 11 && abs((*elektron)->id()) <= 16 && abs((*elektron)->id()) % 2 == 1 ) break;
if ( elektron == xproc.end() ) return false;
PDPtr e = *elektron;
xproc.erase(elektron);
PDVector::iterator neutrino = xproc.begin();
for ( ; neutrino != xproc.end(); ++neutrino )
if ( abs((*neutrino)->id()) >= 11 && abs((*neutrino)->id()) <= 16 && abs((*neutrino)->id()) % 2 == 0 ) break;
if ( neutrino == xproc.end() ) return false;
PDPtr n = *neutrino;
xproc.erase(neutrino);
PDVector::iterator quark = xproc.begin();
for ( ; quark != xproc.end(); ++quark )
if ( abs((*quark)->id()) >= 1 && abs((*quark)->id()) <= 6 ) {
assert( (*quark)->hardProcessMass() == ZERO );
break;
}
if ( quark == xproc.end() ) return false;
PDPtr q1 = *quark;
xproc.erase(quark);
quark = xproc.begin();
for ( ; quark != xproc.end(); ++quark )
if ( abs((*quark)->id()) >= 1 && abs((*quark)->id()) <= 6 ) {
assert( (*quark)->hardProcessMass() == ZERO );
break;
}
if ( quark == xproc.end() ) return false;
PDPtr q2 = *quark;
xproc.erase(quark);
quark = xproc.begin();
for ( ; quark != xproc.end(); ++quark )
if ( abs((*quark)->id()) >= 1 && abs((*quark)->id()) <= 6 ) {
assert( (*quark)->hardProcessMass() == ZERO );
break;
}
if ( quark == xproc.end() ) return false;
PDPtr q3 = *quark;
xproc.erase(quark);
quark = xproc.begin();
for ( ; quark != xproc.end(); ++quark )
if ( abs((*quark)->id()) >= 1 && abs((*quark)->id()) <= 6 ) {
assert( (*quark)->hardProcessMass() == ZERO );
break;
}
if ( quark == xproc.end() ) return false;
PDPtr q4 = *quark;
xproc.erase(quark);
if ( q1->id() == -q2->id() ) {
if ( q3->iCharge() + q4->iCharge() + e->iCharge() != PDT::ChargeNeutral ) return false;
if ( theDiagonal && SU2Helper::family(q3) != SU2Helper::family(q4) ) return false;
} else if ( q1->id() == -q3->id() ) {
if ( q2->iCharge() + q4->iCharge() + e->iCharge() != PDT::ChargeNeutral ) return false;
if ( theDiagonal && SU2Helper::family(q2) != SU2Helper::family(q4) ) return false;
} else if ( q1->id() == -q4->id() ) {
if ( q2->iCharge() + q3->iCharge() + e->iCharge() != PDT::ChargeNeutral ) return false;
if ( theDiagonal && SU2Helper::family(q2) != SU2Helper::family(q3) ) return false;
} else if ( q2->id() == -q3->id() ) {
if ( q1->iCharge() + q4->iCharge() + e->iCharge() != PDT::ChargeNeutral ) return false;
if ( theDiagonal && SU2Helper::family(q1) != SU2Helper::family(q4) ) return false;
} else if ( q2->id() == -q4->id() ) {
if ( q1->iCharge() + q3->iCharge() + e->iCharge() != PDT::ChargeNeutral ) return false;
if ( theDiagonal && SU2Helper::family(q1) != SU2Helper::family(q3) ) return false;
} else if ( q3->id() == -q4->id() ) {
if ( q1->iCharge() + q2->iCharge() + e->iCharge() != PDT::ChargeNeutral ) return false;
if ( theDiagonal && SU2Helper::family(q1) != SU2Helper::family(q2) ) return false;
} else return false;
if ( SU2Helper::family(e) != SU2Helper::family(n) ) return false;
return xproc.empty();
}
void MatchboxAmplitudelnuqqbarqqbar::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
setupLeptons(0,amplitudeMomentum(0),1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
momentum(4,amplitudeMomentum(4));
momentum(5,amplitudeMomentum(5));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudelnuqqbarqqbar::evaluate(size_t a, const vector<int>& hel, Complex& largeN) {
const LorentzVector<Complex>& leptonCurrent = llbarLeftCurrent(0,hel[0],1,hel[1]);
Complex Current2345 =
hel[2] == 1 && hel[3] == 1 && abs(hel[4]+hel[5]) == 2 &&
abs(amplitudePartonData()[4]->id()) == abs(amplitudePartonData()[5]->id()) ?
leptonCurrent.dot(qqbarqqbarLeftCurrent(2,hel[2],3,hel[3],4,hel[4],5,hel[5])) : 0.;
Complex Current4523 =
hel[4] == 1 && hel[5] == 1 && abs(hel[2]+hel[3]) == 2 &&
abs(amplitudePartonData()[2]->id()) == abs(amplitudePartonData()[3]->id()) ?
leptonCurrent.dot(qqbarqqbarLeftCurrent(4,hel[4],5,hel[5],2,hel[2],3,hel[3])) : 0.;
Complex Current2543 =
hel[2] == 1 && hel[5] == 1 && abs(hel[4]+hel[3]) == 2 &&
abs(amplitudePartonData()[4]->id()) == abs(amplitudePartonData()[3]->id()) ?
-leptonCurrent.dot(qqbarqqbarLeftCurrent(2,hel[2],5,hel[5],4,hel[4],3,hel[3])) : 0.;
Complex Current4325 =
hel[4] == 1 && hel[3] == 1 && abs(hel[2]+hel[5]) == 2 &&
abs(amplitudePartonData()[2]->id()) == abs(amplitudePartonData()[5]->id()) ?
-leptonCurrent.dot(qqbarqqbarLeftCurrent(4,hel[4],3,hel[3],2,hel[2],5,hel[5])) : 0.;
Complex ckmelement23 = 1.;
Complex ckmelement45 = 1.;
if ( !theDiagonal ) {
bool wPlus = ( abs(amplitudePartonData()[0]->id()) % 2 == 0 ) ?
amplitudePartonData()[1]->id() < 0:
amplitudePartonData()[0]->id() < 0;
pair<int,int> tmp23(
SU2Helper::family(amplitudePartonData()[2])-1,
SU2Helper::family(amplitudePartonData()[3])-1);
pair<int,int> tmp45(
SU2Helper::family(amplitudePartonData()[4])-1,
SU2Helper::family(amplitudePartonData()[5])-1);
if ( amplitudePartonData()[3]->id() < 0 ) swap(tmp23.first,tmp23.second);
if ( amplitudePartonData()[5]->id() < 0 ) swap(tmp45.first,tmp45.second);
ckmelement23 = theCKM[tmp23.first][tmp23.second];
ckmelement45 = theCKM[tmp45.first][tmp45.second];
if ( !wPlus ) {
ckmelement23 = conj(ckmelement23);
ckmelement45 = conj(ckmelement45);
}
}
Complex wPropergator =
1./Complex(((amplitudeMomentum(0)+amplitudeMomentum(1)).m2()-sqr(MW))/lastSHat(),MW*GW/lastSHat());
Complex wVertices23 =
2.*SM().alphaEMMZ()*Constants::pi/SM().sin2ThetaW()*ckmelement23;
Complex wVertices45 =
2.*SM().alphaEMMZ()*Constants::pi/SM().sin2ThetaW()*ckmelement45;
Complex sVertices =
4.*Constants::pi*SM().alphaS();
Complex res2345 =
Complex(0.,-1.)*wPropergator*sVertices*Current2345*wVertices23;
Complex res2543 =
Complex(0.,-1.)*wPropergator*sVertices*Current2543*wVertices23;
Complex res4523 =
Complex(0.,-1.)*wPropergator*sVertices*Current4523*wVertices45;
Complex res4325 =
Complex(0.,-1.)*wPropergator*sVertices*Current4325*wVertices45;
double Nc = SM().Nc();
Complex resLeading = 0.;
Complex resSubLeading = 0.;
if ( amplitudeToColourMap()[2] == 0 && amplitudeToColourMap()[3] == 1 &&
amplitudeToColourMap()[4] == 2 && amplitudeToColourMap()[5] == 3 ) {
if ( a == 0 ) { //(23)(45)
resLeading = res2543 + res4325;
resSubLeading = res2345 + res4523;
} else if ( a == 1 ) { //(25)(43)
resLeading = res2345 + res4523;
resSubLeading = res2543 + res4325;
} else assert(false);
} else if ( amplitudeToColourMap()[2] == 0 && amplitudeToColourMap()[3] == 3 &&
amplitudeToColourMap()[4] == 2 && amplitudeToColourMap()[5] == 1 ) {
if ( a == 0 ) { // (25)(43)
resLeading = res2345 + res4523;
resSubLeading = res2543 + res4325;
} else if ( a == 1 ) { // (23)(45)
resLeading = res2543 + res4325;
resSubLeading = res2345 + res4523;
} else assert(false);
} else if ( amplitudeToColourMap()[2] == 2 && amplitudeToColourMap()[3] == 3 &&
amplitudeToColourMap()[4] == 0 && amplitudeToColourMap()[5] == 1 ) {
if ( a == 0 ) { //(23)(45)
resLeading = res2543 + res4325;
resSubLeading = res2345 + res4523;
} else if ( a == 1 ) { //(25)(43)
resLeading = res2345 + res4523;
resSubLeading = res2543 + res4325;
} else assert(false);
} else if ( amplitudeToColourMap()[2] == 2 && amplitudeToColourMap()[3] == 1 &&
amplitudeToColourMap()[4] == 0 && amplitudeToColourMap()[5] == 3 ) {
if ( a == 0 ) { //(25)(43)
resLeading = res2345 + res4523;
resSubLeading = res2543 + res4325;
} else if ( a == 1 ) { //(23)(45)
resLeading = res2543 + res4325;
resSubLeading = res2345 + res4523;
} else assert(false);
} else assert(false);
resSubLeading *= -1./Nc;
largeN = resLeading/2.;
return (resLeading + resSubLeading)/2.;
}
void MatchboxAmplitudelnuqqbarqqbar::persistentOutput(PersistentOStream & os) const {
os << theDiagonal << theCKM ;
}
void MatchboxAmplitudelnuqqbarqqbar::persistentInput(PersistentIStream & is, int) {
is >> theDiagonal >> theCKM ;
}
DescribeClass<MatchboxAmplitudelnuqqbarqqbar,MatchboxAmplitude>
describeHerwigMatchboxAmplitudelnuqqbarqqbar("Herwig::MatchboxAmplitudelnuqqbarqqbar", "HwMatchboxBuiltin.so");
void MatchboxAmplitudelnuqqbarqqbar::Init() {
static ClassDocumentation<MatchboxAmplitudelnuqqbarqqbar> documentation
("MatchboxAmplitudelnuqqbarqqbar");
static Switch<MatchboxAmplitudelnuqqbarqqbar,bool> interfaceDiagonal
("Diagonal",
"Use a diagonal CKM matrix (ignoring the CKM object of the StandardModel).",
&MatchboxAmplitudelnuqqbarqqbar::theDiagonal, false, false, false);
static SwitchOption interfaceDiagonalYes
(interfaceDiagonal,
"Yes",
"Use a diagonal CKM matrix.",
true);
static SwitchOption interfaceDiagonalNo
(interfaceDiagonal,
"No",
"Use the CKM object as used by the StandardModel.",
false);
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarqqbar.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarqqbar.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarqqbar.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudelnuqqbarqqbar.h
@@ -1,181 +1,176 @@
// -*- C++ -*-
//
// MatchboxAmplitudelnuqqbarqqbar.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudelnuqqbarqqbar_H
#define Herwig_MatchboxAmplitudelnuqqbarqqbar_H
//
// This is the declaration of the MatchboxAmplitudelnuqqbarqqbar class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SU2Helper.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Thomas Schuh
*
* \brief MatchboxAmplitudelnuqqbarqqbar
*/
class MatchboxAmplitudelnuqqbarqqbar: public MatchboxAmplitude, public MatchboxCurrents {
public:
/**
* The default constructor.
*/
MatchboxAmplitudelnuqqbarqqbar();
/**
- * The destructor.
- */
- virtual ~MatchboxAmplitudelnuqqbarqqbar();
-
- /**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const { return 2; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 2; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Return true, if one loop corrections are given in the conventions
* of BDK.
*/
virtual bool isBDK() const { return true; }
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
/**
* 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:
/**
* 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;
/**
* 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:
/**
* True, if a diagonal CKM matrix should be assumed. This ignores
* the CKM object of the StandardModel.
*/
bool theDiagonal;
/**
* The ckm.
*/
vector< vector<Complex> > theCKM;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudelnuqqbarqqbar & operator=(const MatchboxAmplitudelnuqqbarqqbar &) = delete;
};
}
#endif /* Herwig_MatchboxAmplitudelnuqqbarqqbar_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbar.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbar.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbar.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbar.cc
@@ -1,188 +1,184 @@
// -*- C++ -*-
//
// MatchboxAmplitudeqqbarttbar.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxAmplitudeqqbarttbar class.
//
#include "MatchboxAmplitudeqqbarttbar.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudeqqbarttbar::MatchboxAmplitudeqqbarttbar() {}
-MatchboxAmplitudeqqbarttbar::~MatchboxAmplitudeqqbarttbar() {}
-
IBPtr MatchboxAmplitudeqqbarttbar::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudeqqbarttbar::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudeqqbarttbar::setupParams(map<string, double> &MGParams){
// create parameter map for adapted Madgraph amplitude to use
MGParams["aS"] = SM().alphaS();
MGParams["MZ"] = getParticleData(ParticleID::Z0) -> hardProcessMass()/GeV;
MGParams["MW"] = getParticleData(ParticleID::Wplus) -> hardProcessMass()/GeV;
MGParams["MH"] = getParticleData(ParticleID::h0) -> hardProcessMass()/GeV;
MGParams["MT"] = getParticleData(ParticleID::t) -> hardProcessMass()/GeV;
MGParams["MB"] = getParticleData(ParticleID::b) -> hardProcessMass()/GeV;
MGParams["MTA"] = getParticleData(ParticleID::tauminus)-> hardProcessMass()/GeV;
MGParams["WW"] = getParticleData(ParticleID::Wplus) ->hardProcessWidth()/GeV;
MGParams["WZ"] = getParticleData(ParticleID::Z0) ->hardProcessWidth()/GeV;
MGParams["WH"] = getParticleData(ParticleID::h0) ->hardProcessWidth()/GeV;
MGParams["WT"] = getParticleData(ParticleID::t) ->hardProcessWidth()/GeV;
MGParams["WB"] = getParticleData(ParticleID::b) ->hardProcessWidth()/GeV;
MGParams["GF"] = SM().fermiConstant()*GeV2;
MGParams["aEWM1"] = 1./SM().alphaEMMZ();
return;
}
void MatchboxAmplitudeqqbarttbar::doinit() {
setupParams(MGParams_);
MatchboxAmplitude::doinit();
nPoints(4);
}
void MatchboxAmplitudeqqbarttbar::doinitrun() {
setupParams(MGParams_);
MatchboxAmplitude::doinitrun();
nPoints(4);
}
bool MatchboxAmplitudeqqbarttbar::canHandle(const PDVector& proc) const {
// check process is qqbar > ttbar
if ( proc.size() != 4 )
return false;
PDVector xproc = proc;
PDVector::iterator top = xproc.begin();
long topId = 0;
for ( ; top != xproc.end(); ++top )
if ( (**top).id() == 6 ) {
break;
}
if ( top == xproc.end() )
return false;
topId = (**top).id();
xproc.erase(top);
PDVector::iterator antiTop = xproc.begin();
for ( ; antiTop != xproc.end(); ++antiTop )
if ( (**antiTop).id() == -topId ) {
break;
}
if ( antiTop == xproc.end() )
return false;
xproc.erase(antiTop);
PDVector::iterator quark = xproc.begin();
long quarkId = 0;
for ( ; quark != xproc.end(); ++quark )
if ( abs((**quark).id()) < 6 &&
(**quark).id() > 0 ) {
break;
}
if ( quark == xproc.end() )
return false;
quarkId = (**quark).id();
xproc.erase(quark);
PDVector::iterator antiQuark = xproc.begin();
for ( ; antiQuark != xproc.end(); ++antiQuark )
if ( (**antiQuark).id() == -quarkId ) {
break;
}
if ( antiQuark == xproc.end() )
return false;
xproc.erase(antiQuark);
return xproc.empty();
}
void MatchboxAmplitudeqqbarttbar::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
momentum(0,amplitudeMomentum(0));
momentum(1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudeqqbarttbar::evaluate(size_t a, const vector<int>& hel, Complex& largeN) {
// set up momenta to pass into Madgraph amplitude
vector<double*> p;
p.push_back(mom0); p.push_back(mom1); p.push_back(mom2); p.push_back(mom3);
for (int ip=0; ip<4; ++ip){
p[ip][0] = abs(momentum(ip).e())<1.e-13 ? 0.0:double(momentum(ip).e()*amplitudeScale()/GeV);
p[ip][1] = abs(momentum(ip).x())<1.e-13 ? 0.0:double(momentum(ip).x()*amplitudeScale()/GeV);
p[ip][2] = abs(momentum(ip).y())<1.e-13 ? 0.0:double(momentum(ip).y()*amplitudeScale()/GeV);
p[ip][3] = abs(momentum(ip).z())<1.e-13 ? 0.0:double(momentum(ip).z()*amplitudeScale()/GeV);
}
// calculate amplitudes
vector<complex<double> > amplitudes;
MG_qqx2ttx process;
process.initProc(MGParams_);
process.setMomenta(p);
process.sigmaKin(amplitudes, hel);
// calculate colour flows
complex<double> matrixElement;
if (a==0) matrixElement = amplitudes[0]*( 1./6.);
else if (a==1) matrixElement = amplitudes[0]*(-1./2.);
else assert(false);
largeN = matrixElement;
return matrixElement;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudeqqbarttbar::persistentOutput(PersistentOStream &) const {}
void MatchboxAmplitudeqqbarttbar::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudeqqbarttbar,MatchboxAmplitude>
describeHerwigMatchboxAmplitudeqqbarttbar("Herwig::MatchboxAmplitudeqqbarttbar", "HwMatchboxBuiltin.so");
void MatchboxAmplitudeqqbarttbar::Init() {
static ClassDocumentation<MatchboxAmplitudeqqbarttbar> documentation
("MatchboxAmplitudeqqbarttbar");
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbar.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbar.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbar.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbar.h
@@ -1,201 +1,193 @@
// -*- C++ -*-
//
// MatchboxAmplitudeqqbarttbar.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudeqqbarttbar_H
#define Herwig_MatchboxAmplitudeqqbarttbar_H
//
// This is the declaration of the MatchboxAmplitudeqqbarttbar class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
#include "MG_qqx2ttx.h"
#include "HelAmps_sm.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Alix Wilcock
*
* \brief MatchboxAmplitudeqqbarttbar
*/
class MatchboxAmplitudeqqbarttbar:
public MatchboxAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudeqqbarttbar();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudeqqbarttbar();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const {return 2; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 0; }
/**
* Return true, if this amplitude will not require colour correlations.
*/
virtual bool noCorrelations() const { return false; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
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();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudeqqbarttbar & operator=(const MatchboxAmplitudeqqbarttbar &) = delete;
/**
* Containers for external particle momenta
*/
double mom0 [4];
double mom1 [4];
double mom2 [4];
double mom3 [4];
/**
* Fill MGParams_ with Herwig values of parameters
*/
void setupParams(map<string, double> & MGParams);
/**
* Stores parameters needed in MG_process
*/
map<string,double> MGParams_;
};
}
#endif /* Herwig_MatchboxAmplitudeqqbarttbar_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.cc
@@ -1,219 +1,217 @@
// -*- C++ -*-
//
// MatchboxAmplitudeqqbarttbarg.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MatchboxAmplitudeqqbarttbarg class.
//
#include "MatchboxAmplitudeqqbarttbarg.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/EnumParticles.h"
using namespace Herwig;
MatchboxAmplitudeqqbarttbarg::MatchboxAmplitudeqqbarttbarg() {}
-MatchboxAmplitudeqqbarttbarg::~MatchboxAmplitudeqqbarttbarg() {}
-
IBPtr MatchboxAmplitudeqqbarttbarg::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxAmplitudeqqbarttbarg::fullclone() const {
return new_ptr(*this);
}
void MatchboxAmplitudeqqbarttbarg::setupParams(map<string, double> &MGParams){
// create parameter map for adapted Madgraph amplitude to use
MGParams["aS"] = SM().alphaS();
MGParams["MZ"] = getParticleData(ParticleID::Z0) -> hardProcessMass()/GeV;
MGParams["MW"] = getParticleData(ParticleID::Wplus) -> hardProcessMass()/GeV;
MGParams["MH"] = getParticleData(ParticleID::h0) -> hardProcessMass()/GeV;
MGParams["WW"] = getParticleData(ParticleID::Wplus) ->hardProcessWidth()/GeV;
MGParams["WZ"] = getParticleData(ParticleID::Z0) ->hardProcessWidth()/GeV;
MGParams["WH"] = getParticleData(ParticleID::h0) ->hardProcessWidth()/GeV;
MGParams["MT"] = getParticleData(ParticleID::t) -> hardProcessMass()/GeV;
MGParams["MB"] = getParticleData(ParticleID::b) -> hardProcessMass()/GeV;
MGParams["WT"] = getParticleData(ParticleID::t) ->hardProcessWidth()/GeV;
MGParams["WB"] = getParticleData(ParticleID::b) ->hardProcessWidth()/GeV;
MGParams["MTA"] = getParticleData(ParticleID::tauminus)-> hardProcessMass()/GeV;
MGParams["GF"] = SM().fermiConstant()*GeV2;
MGParams["aEWM1"] = 1./SM().alphaEMMZ();
return;
}
void MatchboxAmplitudeqqbarttbarg::doinit() {
setupParams(MGParams_);
MatchboxAmplitude::doinit();
nPoints(5);
}
void MatchboxAmplitudeqqbarttbarg::doinitrun() {
setupParams(MGParams_);
MatchboxAmplitude::doinitrun();
nPoints(5);
}
bool MatchboxAmplitudeqqbarttbarg::canHandle(const PDVector& proc) const {
// check process is qqbar > ttbarg or some crossing of this
if ( proc.size() != 5 )
return false;
PDVector xproc = proc;
if ( xproc[0]->CC() )
xproc[0] = xproc[0]->CC();
if ( xproc[1]->CC() )
xproc[1] = xproc[1]->CC();
PDVector::iterator top = xproc.begin();
long topId = 0;
for ( ; top != xproc.end(); ++top )
if ( (**top).id() == 6 ) {
break;
}
if ( top == xproc.end() )
return false;
topId = (**top).id();
xproc.erase(top);
PDVector::iterator antiTop = xproc.begin();
for ( ; antiTop != xproc.end(); ++antiTop )
if ( (**antiTop).id() == -topId ) {
break;
}
if ( antiTop == xproc.end() )
return false;
xproc.erase(antiTop);
PDVector::iterator quark = xproc.begin();
long quarkId = 0;
for ( ; quark != xproc.end(); ++quark )
if ( abs((**quark).id()) < 6 &&
(**quark).id() > 0 ) {
break;
}
if ( quark == xproc.end() )
return false;
quarkId = (**quark).id();
xproc.erase(quark);
PDVector::iterator antiQuark = xproc.begin();
for ( ; antiQuark != xproc.end(); ++antiQuark )
if ( (**antiQuark).id() == -quarkId ) {
break;
}
if ( antiQuark == xproc.end() )
return false;
xproc.erase(antiQuark);
return xproc[0]->id() == 21;
}
void MatchboxAmplitudeqqbarttbarg::prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr me) {
if ( !calculateTreeAmplitudes() ) {
MatchboxAmplitude::prepareAmplitudes(me);
return;
}
amplitudeScale(sqrt(lastSHat()));
momentum(0,amplitudeMomentum(0));
momentum(1,amplitudeMomentum(1));
momentum(2,amplitudeMomentum(2));
momentum(3,amplitudeMomentum(3));
momentum(4,amplitudeMomentum(4));
MatchboxAmplitude::prepareAmplitudes(me);
}
Complex MatchboxAmplitudeqqbarttbarg::evaluate(size_t a, const vector<int>& hel, Complex& largeN) {
// check if doing qqbar, qg or qbarg initiated process
int crossed;
cPDVector partons = mePartonData();
if (abs(partons[0]->id())< 6 &&
partons[1]->id()==-partons[0]->id()) crossed=1;
else if (((partons[0]->id()>0 && partons[0]->id()<6) &&
partons[1]->id()==ParticleID::g) ||
((partons[1]->id()>0 && partons[1]->id()<6) &&
partons[0]->id()==ParticleID::g)) crossed=2;
else if (((partons[0]->id()<0 && partons[0]->id()>-6) &&
partons[1]->id()==ParticleID::g) ||
((partons[1]->id()<0 && partons[1]->id()>-6) &&
partons[0]->id()==ParticleID::g)) crossed=3;
else
throw Exception() << "MatchboxAmplitudeqqbarststbarg::evaluate(): Unrecognised process\n"
<< Exception::runerror;
// set up momenta to pass into Madgraph amplitude
vector<double*> p;
p.push_back(mom0); p.push_back(mom1); p.push_back(mom2); p.push_back(mom3); p.push_back(mom4);
for (int ip=0; ip<5; ++ip){
p[ip][0] = abs(momentum(ip).e())<1.e-13 ? 0.0:double(momentum(ip).e()*amplitudeScale()/GeV);
p[ip][1] = abs(momentum(ip).x())<1.e-13 ? 0.0:double(momentum(ip).x()*amplitudeScale()/GeV);
p[ip][2] = abs(momentum(ip).y())<1.e-13 ? 0.0:double(momentum(ip).y()*amplitudeScale()/GeV);
p[ip][3] = abs(momentum(ip).z())<1.e-13 ? 0.0:double(momentum(ip).z()*amplitudeScale()/GeV);
}
// calculate amplitudes
vector<complex<double> > amplitudes;
MG_qqx2ttxg process;
double factor=lastSHat()/GeV2;
process.initProc(MGParams_);
process.setMomenta(p);
process.sigmaKin(amplitudes, hel, crossed);
for (int iamp=0; iamp<int(amplitudes.size()); ++iamp)
amplitudes[iamp]*=sqrt(factor);
complex<double> matrixElement;
complex<double> i = complex<double>(0,1);
// calculate colour flows
if (a==0)
matrixElement = (1./6.)*(amplitudes[1] + amplitudes[2]);
else if (a==1)
matrixElement = 1./2.*( i*amplitudes[0] - amplitudes[1] - amplitudes[3]);
else if (a==2)
matrixElement = (1./6.)*( amplitudes[3] + amplitudes[4]);
else if (a==3)
matrixElement = 1./2.*(-i*amplitudes[0] - amplitudes[2] - amplitudes[4]);
else assert(false);
largeN = matrixElement;
return matrixElement;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxAmplitudeqqbarttbarg::persistentOutput(PersistentOStream &) const {}
void MatchboxAmplitudeqqbarttbarg::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxAmplitudeqqbarttbarg,MatchboxAmplitude>
describeHerwigMatchboxAmplitudeqqbarttbarg("Herwig::MatchboxAmplitudeqqbarttbarg", "HwMatchboxBuiltin.so");
void MatchboxAmplitudeqqbarttbarg::Init() {
static ClassDocumentation<MatchboxAmplitudeqqbarttbarg> documentation
("MatchboxAmplitudeqqbarttbarg");
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxAmplitudeqqbarttbarg.h
@@ -1,202 +1,194 @@
// -*- C++ -*-
//
// MatchboxAmplitudeqqbarttbarg.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxAmplitudeqqbarttbarg_H
#define Herwig_MatchboxAmplitudeqqbarttbarg_H
//
// This is the declaration of the MatchboxAmplitudeqqbarttbarg class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxCurrents.h"
#include "MG_qqx2ttxg.h"
#include "HelAmps_sm.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Alix Wilcock
*
* \brief MatchboxAmplitudeqqbarttbarg
*/
class MatchboxAmplitudeqqbarttbarg:
public MatchboxAmplitude, public MatchboxCurrents {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxAmplitudeqqbarttbarg();
- /**
- * The destructor.
- */
- virtual ~MatchboxAmplitudeqqbarttbarg();
- //@}
-
public:
/**
* Return true, if this amplitude can handle the given process.
*/
virtual bool canHandle(const PDVector&) const;
/**
* Return the (tree-level) order in \f$g_S\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGs() const {return 3; }
/**
* Return the (tree-level) order in \f$g_{EM}\f$ in which this matrix
* element is given.
*/
virtual unsigned int orderInGem() const { return 0; }
/**
* Return true, if this amplitude will not require colour correlations.
*/
virtual bool noCorrelations() const { return true; }
/**
* Return true, if this amplitude is capable of calculating one-loop
* (QCD) corrections.
*/
virtual bool haveOneLoop() const { return false; }
/**
* Calculate the tree level amplitudes for the phasespace point
* stored in lastXComb.
*/
virtual void prepareAmplitudes(Ptr<MatchboxMEBase>::tcptr);
/**
* Evaluate the amplitude for the given colour tensor id and
* helicity assignment
*/
virtual Complex evaluate(size_t, const vector<int>&, Complex&);
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
virtual Energy2 mu2() const { return lastSHat(); }
/**
* Flush all cashes.
*/
virtual void flushCaches() {
MatchboxCurrents::reset();
MatchboxAmplitude::flushCaches();
}
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();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxAmplitudeqqbarttbarg & operator=(const MatchboxAmplitudeqqbarttbarg &) = delete;
/**
* Containers for external particle momenta
*/
double mom0 [4];
double mom1 [4];
double mom2 [4];
double mom3 [4];
double mom4 [4];
/**
* Fill MGParams_ with Herwig values of parameters
*/
void setupParams(map<string, double> & MGParams);
/**
* Stores parameters needed in MG_process
*/
map<string,double> MGParams_;
};
}
#endif /* Herwig_MatchboxAmplitudeqqbarttbarg_H */
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.cc b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.cc
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.cc
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.cc
@@ -1,91 +1,89 @@
// -*- C++ -*-
//
// MatchboxZGammaAmplitude.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxZGammaAmplitude class.
//
#include "MatchboxZGammaAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxZGammaAmplitude::MatchboxZGammaAmplitude()
: MatchboxAmplitude(), theIncludeZ(true), theIncludeGamma(true) {}
-MatchboxZGammaAmplitude::~MatchboxZGammaAmplitude() {}
-
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxZGammaAmplitude::persistentOutput(PersistentOStream & os) const {
os << theIncludeZ << theIncludeGamma;
}
void MatchboxZGammaAmplitude::persistentInput(PersistentIStream & is, int) {
is >> theIncludeZ >> theIncludeGamma;
}
// *** 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<MatchboxZGammaAmplitude,MatchboxAmplitude>
describeHerwigMatchboxZGammaAmplitude("Herwig::MatchboxZGammaAmplitude", "HwMatchboxBuiltin.so");
void MatchboxZGammaAmplitude::Init() {
static ClassDocumentation<MatchboxZGammaAmplitude> documentation
("There is no documentation for the MatchboxZGammaAmplitude class");
static Switch<MatchboxZGammaAmplitude,bool> interfaceIncludeZ
("IncludeZ",
"Include the Z contribution.",
&MatchboxZGammaAmplitude::theIncludeZ, true, false, false);
static SwitchOption interfaceIncludeZYes
(interfaceIncludeZ,
"Yes",
"",
true);
static SwitchOption interfaceIncludeZNo
(interfaceIncludeZ,
"No",
"",
false);
static Switch<MatchboxZGammaAmplitude,bool> interfaceIncludeGamma
("IncludeGamma",
"Include the photon contribution.",
&MatchboxZGammaAmplitude::theIncludeGamma, true, false, false);
static SwitchOption interfaceIncludeGammaYes
(interfaceIncludeGamma,
"Yes",
"",
true);
static SwitchOption interfaceIncludeGammaNo
(interfaceIncludeGamma,
"No",
"",
false);
}
diff --git a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.h b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.h
--- a/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.h
+++ b/MatrixElement/Matchbox/Builtin/Amplitudes/MatchboxZGammaAmplitude.h
@@ -1,109 +1,101 @@
// -*- C++ -*-
//
// MatchboxZGammaAmplitude.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxZGammaAmplitude_H
#define Herwig_MatchboxZGammaAmplitude_H
//
// This is the declaration of the MatchboxZGammaAmplitude class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
namespace Herwig {
using namespace ThePEG;
/**
* Here is the documentation of the MatchboxZGammaAmplitude class.
*
* @see \ref MatchboxZGammaAmplitudeInterfaces "The interfaces"
* defined for MatchboxZGammaAmplitude.
*/
class MatchboxZGammaAmplitude: public MatchboxAmplitude {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxZGammaAmplitude();
- /**
- * The destructor.
- */
- virtual ~MatchboxZGammaAmplitude();
- //@}
-
public:
/**
* Return true, if the Z contribution should be taken into account
*/
bool includeZ() const { return theIncludeZ; }
/**
* Return true, if the gamma contribution should be taken into account
*/
bool includeGamma() const { return theIncludeGamma; }
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).
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxZGammaAmplitude & operator=(const MatchboxZGammaAmplitude &) = delete;
/**
* True, if the Z contribution should be taken into account
*/
bool theIncludeZ;
/**
* True, if the gamma contribution should be taken into account
*/
bool theIncludeGamma;
};
}
#endif /* Herwig_MatchboxZGammaAmplitude_H */
diff --git a/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.cc b/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.cc
--- a/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.cc
+++ b/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.cc
@@ -1,151 +1,149 @@
// -*- C++ -*-
//
// IdentifiedParticleCut.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IdentifiedParticleCut class.
//
#include "IdentifiedParticleCut.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/CurrentGenerator.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IdentifiedParticleCut::IdentifiedParticleCut()
: thePtMin(0.*GeV), thePtMax(Constants::MaxEnergy) {}
-IdentifiedParticleCut::~IdentifiedParticleCut() {}
-
IBPtr IdentifiedParticleCut::clone() const {
return new_ptr(*this);
}
IBPtr IdentifiedParticleCut::fullclone() const {
return new_ptr(*this);
}
bool IdentifiedParticleCut::passCuts(tcCutsPtr parent,
tcPDPtr ptype, LorentzMomentum p) const {
if ( !matcher()->check(*ptype) ||
( thePtMin == ZERO && thePtMax == Constants::MaxEnergy &&
theYRanges.empty() ) )
return true;
double weight = 1.0;
if ( !parent->isInside<CutTypes::Momentum>(p.perp(),ptMin(),ptMax(),weight) ) {
parent->lastCutWeight(0.0);
return false;
}
double y = p.rapidity() + parent->currentYHat();
for ( vector<pair<double,double> >::const_iterator dy = yRanges().begin();
dy != yRanges().end(); ++dy ) {
if ( !parent->isInside<CutTypes::Rapidity>(y,dy->first,dy->second,weight) ) {
parent->lastCutWeight(0.0);
return false;
}
}
parent->lastCutWeight(weight);
return true;
}
void IdentifiedParticleCut::describe() const {
CurrentGenerator::log()
<< "IdentifiedParticleCut '" << name() << "' matching "
<< "'" << matcher()->name() << "'";
CurrentGenerator::log() << " within:\n";
CurrentGenerator::log()
<< "pt = " << ptMin()/GeV << " .. " << ptMax()/GeV << " GeV\n";
for ( vector<pair<double,double> >::const_iterator r = yRanges().begin();
r != yRanges().end(); ++r ) {
CurrentGenerator::log() << "y = " << r->first << " .. " << r->second << "\n";
}
}
string IdentifiedParticleCut::doYRange(string in) {
istringstream ins(in);
double first, second;
ins >> first >> second;
if ( first > second )
swap(first,second);
theYRanges.push_back(make_pair(first,second));
return "";
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IdentifiedParticleCut::persistentOutput(PersistentOStream & os) const {
os << ounit(thePtMin,GeV) << ounit(thePtMax,GeV)
<< theYRanges << theMatcher;
}
void IdentifiedParticleCut::persistentInput(PersistentIStream & is, int) {
is >> iunit(thePtMin,GeV) >> iunit(thePtMax,GeV)
>> theYRanges >> theMatcher;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<IdentifiedParticleCut,OneCutBase>
describeHerwigIdentifiedParticleCut("Herwig::IdentifiedParticleCut", "HwMatchboxCuts.so");
void IdentifiedParticleCut::Init() {
static ClassDocumentation<IdentifiedParticleCut> documentation
("IdentifiedParticleCut implements cuts on single momenta.");
static Parameter<IdentifiedParticleCut,Energy> interfacePtMin
("PtMin",
"The minimum pt required.",
&IdentifiedParticleCut::thePtMin, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<IdentifiedParticleCut,Energy> interfacePtMax
("PtMax",
"The maximum pt allowed.",
&IdentifiedParticleCut::thePtMax, GeV, Constants::MaxEnergy, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Command<IdentifiedParticleCut> interfaceYRange
("YRange",
"Insert a rapidity range.",
&IdentifiedParticleCut::doYRange, false);
static Reference<IdentifiedParticleCut,MatcherBase> interfaceMatcher
("Matcher",
"A matcher for particles to cut on.",
&IdentifiedParticleCut::theMatcher, false, false, true, false, false);
}
diff --git a/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.h b/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.h
--- a/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.h
+++ b/MatrixElement/Matchbox/Cuts/IdentifiedParticleCut.h
@@ -1,194 +1,186 @@
// -*- C++ -*-
//
// IdentifiedParticleCut.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_IdentifiedParticleCut_H
#define Herwig_IdentifiedParticleCut_H
//
// This is the declaration of the IdentifiedParticleCut class.
//
#include "ThePEG/Cuts/OneCutBase.h"
#include "ThePEG/PDT/MatcherBase.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IdentifiedParticleCut implements cuts on single momenta.
*
* @see \ref IdentifiedParticleCutInterfaces "The interfaces"
* defined for IdentifiedParticleCut.
*/
class IdentifiedParticleCut: public OneCutBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IdentifiedParticleCut();
- /**
- * The destructor.
- */
- virtual ~IdentifiedParticleCut();
- //@}
-
public:
/** @name Virtual functions to be overridden by sub-classes. */
//@{
/**
* Return the minimum allowed value of the transverse momentum of an
* outgoing parton.
*/
virtual Energy minKT(tcPDPtr) const { return ZERO; }
/**
* Return the minimum allowed pseudo-rapidity of an outgoing parton
* of the given type. The pseudo-rapidity is measured in the lab
* system.
*/
virtual double minEta(tcPDPtr) const { return -Constants::MaxRapidity; }
/**
* Return the maximum allowed pseudo-rapidity of an outgoing parton
* of the given type. The pseudo-rapidity is measured in the lab
* system.
*/
virtual double maxEta(tcPDPtr) const { return Constants::MaxRapidity; }
/**
* Return true if a particle with type \a ptype and momentum \a p
* passes the cuts. The \a parent contains information about the
* kinematics of the hard sub-process.
*/
virtual bool passCuts(tcCutsPtr parent,
tcPDPtr ptype, LorentzMomentum p) const;
/**
* Describe the currently active cuts in the log file.
*/
virtual void describe() const;
//@}
public:
/**
* Return the minimum pt.
*/
Energy ptMin() const { return thePtMin; }
/**
* Return the maximum pt.
*/
Energy ptMax() const { return thePtMax; }
/**
* Return the rapidity ranges.
*/
const vector<pair<double,double> >& yRanges() const { return theYRanges; }
/**
* Return the matcher for particles to cut on.
*/
Ptr<MatcherBase>::tptr matcher() const { return theMatcher; }
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* Command to insert a rapidity range
*/
string doYRange(string);
/**
* The minimum pt.
*/
Energy thePtMin;
/**
* The maximum pt.
*/
Energy thePtMax;
/**
* The rapidity ranges.
*/
vector<pair<double,double> > theYRanges;
/**
* A matcher for particles to cut on.
*/
Ptr<MatcherBase>::ptr theMatcher;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IdentifiedParticleCut & operator=(const IdentifiedParticleCut &) = delete;
};
}
#endif /* Herwig_IdentifiedParticleCut_H */
diff --git a/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.cc b/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.cc
--- a/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.cc
+++ b/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.cc
@@ -1,195 +1,193 @@
// -*- C++ -*-
//
// MatchboxDeltaRCut.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MatchboxDeltaRCut class.
//
#include "MatchboxDeltaRCut.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/CurrentGenerator.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxDeltaRCut::MatchboxDeltaRCut()
: theDeltaRMin(0.0), theDeltaRMax(Constants::MaxRapidity),
theDeltaYMin(0.0), theDeltaYMax(Constants::MaxRapidity),
theDeltaPhiMin(0.0), theDeltaPhiMax(2.0*Constants::pi) {}
-MatchboxDeltaRCut::~MatchboxDeltaRCut() {}
-
IBPtr MatchboxDeltaRCut::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxDeltaRCut::fullclone() const {
return new_ptr(*this);
}
bool MatchboxDeltaRCut::passCuts(tcCutsPtr parent, tcPDPtr pitype, tcPDPtr pjtype,
LorentzMomentum pi, LorentzMomentum pj,
bool inci, bool incj) const {
bool match = false;
if ( theFirstMatcher->check(*pitype) && theSecondMatcher->check(*pjtype) ) match = true;
if ( theFirstMatcher->check(*pjtype) && theSecondMatcher->check(*pitype) ) match = true;
if ( !match ||
(theDeltaRMin == 0.0 && theDeltaRMax == Constants::MaxRapidity &&
theDeltaYMin == 0.0 && theDeltaYMax == Constants::MaxRapidity &&
theDeltaPhiMin == 0.0 && theDeltaPhiMax == 2.0*Constants::pi) ) return true;
if ( inci || incj ) return true;
double weight = 1.0;
double dY = abs(pi.rapidity() - pj.rapidity());
double dPhi = abs(pi.phi() - pj.phi());
if ( dPhi > Constants::pi ) dPhi = 2.0*Constants::pi - dPhi;
double dR = sqrt(sqr(dY) + sqr(dPhi));
if ( !parent->isInside<CutTypes::Rapidity>(dY,deltaYMin(),deltaYMax(),weight) )
{
parent->lastCutWeight(0.0);
return false;
}
if ( !parent->isInside<CutTypes::Azimuth>(dPhi,deltaPhiMin(),deltaPhiMax(),weight) )
{
parent->lastCutWeight(0.0);
return false;
}
if ( !parent->isInside<CutTypes::Rapidity>(dR,deltaRMin(),deltaRMax(),weight) )
{
parent->lastCutWeight(0.0);
return false;
}
parent->lastCutWeight(weight);
return true;
}
void MatchboxDeltaRCut::describe() const {
CurrentGenerator::log()
<< fullName() << "\n"
<< "matching distances between: '"
<< theFirstMatcher->name() << "' and '"
<< theSecondMatcher->name() << "':\n"
<< "DeltaRMin = " << theDeltaRMin << " \n"
<< "DeltaRMax = " << theDeltaRMax << " \n"
<< "DeltaPhiMin = " << theDeltaPhiMin << " \n"
<< "DeltaPhiMax = " << theDeltaPhiMax << " \n"
<< "DeltaYMin = " << theDeltaYMin << " \n"
<< "DeltaYMax = " << theDeltaYMax << " \n\n";
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxDeltaRCut::persistentOutput(PersistentOStream & os) const {
os << theDeltaYMin << theDeltaYMax
<< theDeltaPhiMin << theDeltaPhiMax
<< theDeltaRMin << theDeltaRMax
<< theFirstMatcher << theSecondMatcher;
}
void MatchboxDeltaRCut::persistentInput(PersistentIStream & is, int) {
is >> theDeltaYMin >> theDeltaYMax
>> theDeltaPhiMin >> theDeltaPhiMax
>> theDeltaRMin >> theDeltaRMax
>> theFirstMatcher >> theSecondMatcher;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxDeltaRCut,TwoCutBase>
describeHerwigMatchboxDeltaRCut("Herwig::MatchboxDeltaRCut", "HwMatchboxCuts.so");
void MatchboxDeltaRCut::Init() {
static ClassDocumentation<MatchboxDeltaRCut> documentation
("This class implements cuts on legoplot, rapidity and azimuthal separation, "
"i.e. on the \\f$\\Delta R\\f$-measure and on \\f$\\Delta Y\\f$ and \\f$\\Delta \\phi\\f$. "
"By default the cuts are only applied to coloured particles, but "
"may optionally be applied to all particle types. ");
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaRMin
("DeltaRMin",
"The minimum allowed for the legoplot distance "
"\\f$\\Delta R_{ij}=\\sqrt{\\Delta \\phi_{ij}^2+\\Delta Y_{ij}^2}\\f$ ",
&MatchboxDeltaRCut::theDeltaRMin, 0.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaRMax
("DeltaRMax",
"The maximum allowed for the legoplot distance "
"\\f$\\Delta R_{ij}=\\sqrt{\\Delta \\phi_{ij}^2+\\Delta Y_{ij}^2}\\f$ ",
&MatchboxDeltaRCut::theDeltaRMax, Constants::MaxRapidity, 0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaPhiMin
("DeltaPhiMin",
"The minimum allowed for the azimuthal separation "
"\\f$\\Delta \\phi_{ij}\\f$ ",
&MatchboxDeltaRCut::theDeltaPhiMin, 0.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaPhiMax
("DeltaPhiMax",
"The maximum allowed for the azimuthal separation "
"\\f$\\Delta \\phi_{ij}\\f$ ",
&MatchboxDeltaRCut::theDeltaPhiMax, 2.0*Constants::pi, 0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaYMin
("DeltaYMin",
"The minimum allowed for the rapidity separation "
"\\f$\\Delta Y_{ij}\\f$ ",
&MatchboxDeltaRCut::theDeltaYMin, 0.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxDeltaRCut,double> interfaceDeltaYMax
("DeltaYMax",
"The maximum allowed for the rapidity separation "
"\\f$\\Delta Y_{ij}\\f$ ",
&MatchboxDeltaRCut::theDeltaYMax, Constants::MaxRapidity, 0, 0,
false, false, Interface::lowerlim);
static Reference<MatchboxDeltaRCut,MatcherBase> interfaceFirstMatcher
("FirstMatcher",
"Matcher for first particle of type pitype in the pair (pitype,pjtype). "
"If non-null only particles matching this object will be affected "
"by the cut. ",
&MatchboxDeltaRCut::theFirstMatcher, true, false, true, true, false);
// &MatchboxDeltaRCut::theFirstMatcher, false, false, true, false, false);
static Reference<MatchboxDeltaRCut,MatcherBase> interfaceSecondMatcher
("SecondMatcher",
"Matcher for second particle of type pjtype in the pair (pitype,pjtype). "
"If non-null only particles matching this object will be affected "
"by the cut. ",
&MatchboxDeltaRCut::theSecondMatcher, true, false, true, true, false);
// &MatchboxDeltaRCut::theSecondMatcher, false, false, true, false, false);
}
diff --git a/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.h b/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.h
--- a/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.h
+++ b/MatrixElement/Matchbox/Cuts/MatchboxDeltaRCut.h
@@ -1,233 +1,225 @@
// -*- C++ -*-
//
// MatchboxDeltaRCut.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxDeltaRCut_H
#define Herwig_MatchboxDeltaRCut_H
//
// This is the declaration of the MatchboxDeltaRCut class.
//
#include "ThePEG/Cuts/TwoCutBase.h"
#include "ThePEG/PDT/MatcherBase.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Christian Reuschle
*
* \brief MatchboxDeltaRCut implements cuts related to the separation in the legoplot plane
*
* @see \ref MatchboxDeltaRCutInterfaces "The interfaces"
* defined for MatchboxDeltaRCut.
*/
class MatchboxDeltaRCut: public TwoCutBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxDeltaRCut();
- /**
- * The destructor.
- */
- virtual ~MatchboxDeltaRCut();
- //@}
-
public:
/** @name Virtual functions to be overridden by sub-classes. */
//@{
/**
* Return the minimum allowed value of the longitudinally invariant
* \f$k_\perp\f$-algorithms distance measure. This is defined as
* \f$\min(p_{\perp i}, p_{\perp
* j})\sqrt{\Delta\eta_{ij}^2+\Delta\phi_{ij}^2}\f$ for two outgoing
* partons, or simply \f$p_{\perp i}\f$ or \f$p_{\perp j}\f$ for a
* single outgoing parton. Returns 0 if both partons are incoming. A
* null pointer indicates an incoming parton, hence the type of the
* incoming parton is irrelevant.
*/
virtual Energy minDeltaMeasureCuts(tcPDPtr , tcPDPtr ) const { return ZERO; }
// virtual Energy minDeltaMeasureCuts(tcPDPtr pi, tcPDPtr pj) const { return ZERO; }
/**
* Return the minimum allowed value of the longitudinally invariant
* \f$k_\perp\f$-algorithms distance measure. Returns ZERO.
*/
virtual Energy minKTClus(tcPDPtr , tcPDPtr ) const { return ZERO; }
// virtual Energy minKTClus(tcPDPtr pi, tcPDPtr pj) const { return ZERO; }
/**
* Return the minimum allowed squared invariant mass of two outgoing
* partons of type \a pi and \a pj. Returns zero.
*/
virtual Energy2 minSij(tcPDPtr , tcPDPtr ) const { return ZERO; }
// virtual Energy2 minSij(tcPDPtr pi, tcPDPtr pj) const { return ZERO; }
/**
* Return the minimum allowed value of the negative of the squared
* invariant mass of an incoming parton of type \a pi and an
* outgoing parton of type \a po. Returns zero.
*/
virtual Energy2 minTij(tcPDPtr , tcPDPtr ) const { return ZERO; }
// virtual Energy2 minTij(tcPDPtr pi, tcPDPtr po) const { return ZERO; }
/**
* Return the minimum allowed value of \f$\Delta
* R_{ij}=\sqrt{\Delta\eta_{ij}^2+\Delta\phi_{ij}^2}\f$ of two
* outgoing partons of type \a pi and \a pj. Returns zero.
*/
virtual double minDeltaR(tcPDPtr , tcPDPtr ) const { return ZERO; }
// virtual double minDeltaR(tcPDPtr pi, tcPDPtr pj) const { return ZERO; }
/**
* Return the minimum allowed value of the Durham
* \f$k_\perp\f$-algorithms distance measure. This is defined as
* \f$2\min(E_j^2, E_j^2)(1-\cos\theta_{ij})/\hat{s}\f$ for two
* outgoing partons. Returns zero.
*/
virtual double minDurham(tcPDPtr , tcPDPtr ) const { return 0.0; }
// virtual double minDurham(tcPDPtr pi, tcPDPtr pj) const { return 0.0; }
/**
* Return true if a pair of particles with type \a pitype and \a
* pjtype and momenta \a pi and \a pj respectively passes the
* cuts. \a inci and \a inj indicates if the corresponding particles
* are incoming.
*/
virtual bool passCuts(tcCutsPtr parent, tcPDPtr pitype, tcPDPtr pjtype,
LorentzMomentum pi, LorentzMomentum pj,
bool inci = false, bool incj = false) const;
/**
* Describe the currently active cuts in the log file.
*/
virtual void describe() const;
//@}
public:
/**
* Return the minimum and maximum allowed legoplot separation
*/
double deltaRMin() const { return theDeltaRMin; }
double deltaRMax() const { return theDeltaRMax; }
/**
* Return the minimum and maximum allowed rapidity separation
*/
double deltaYMin() const { return theDeltaYMin; }
double deltaYMax() const { return theDeltaYMax; }
/**
* Return the minimum and maximum allowed azimuthal separation
*/
double deltaPhiMin() const { return theDeltaPhiMin; }
double deltaPhiMax() const { return theDeltaPhiMax; }
/**
* Return the matchers for a pair of particles to cut on. Only a pair
* of particles, matching these objects, will be affected.
*/
Ptr<MatcherBase>::tptr firstMatcher() const { return theFirstMatcher; }
Ptr<MatcherBase>::tptr secondMatcher() const { return theSecondMatcher; }
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 minimum and maximum allowed legoplot separation
*/
double theDeltaRMin;
double theDeltaRMax;
/**
* The minimum and maximum allowed rapidity separation
*/
double theDeltaYMin;
double theDeltaYMax;
/**
* The minimum and maximum allowed azimuthal separation
*/
double theDeltaPhiMin;
double theDeltaPhiMax;
/**
* Matchers for a pair of particles to cut on. Only a pair
* of particles, matching these objects, will be affected.
*/
Ptr<MatcherBase>::ptr theFirstMatcher;
Ptr<MatcherBase>::ptr theSecondMatcher;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxDeltaRCut & operator=(const MatchboxDeltaRCut &) = delete;
};
}
#endif /* Herwig_MatchboxDeltaRCut_H */
diff --git a/MatrixElement/Matchbox/Cuts/MissingPtCut.cc b/MatrixElement/Matchbox/Cuts/MissingPtCut.cc
--- a/MatrixElement/Matchbox/Cuts/MissingPtCut.cc
+++ b/MatrixElement/Matchbox/Cuts/MissingPtCut.cc
@@ -1,178 +1,176 @@
// -*- C++ -*-
//
// MissingPtCut.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MissingPtCut class.
//
#include "MissingPtCut.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/CurrentGenerator.h"
#include "ThePEG/PDT/ParticleData.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MissingPtCut::MissingPtCut()
: thePtMissMin(0.*GeV), thePtMissMax(Constants::MaxEnergy) {}
-MissingPtCut::~MissingPtCut() {}
-
IBPtr MissingPtCut::clone() const {
return new_ptr(*this);
}
IBPtr MissingPtCut::fullclone() const {
return new_ptr(*this);
}
bool MissingPtCut::passCuts(tcCutsPtr parent, const tcPDVector & ptype,
const vector<LorentzMomentum> & p) const {
if ( thePtMissMin == ZERO && thePtMissMax == Constants::MaxEnergy )
return true;
// Energy ptMissSum = 0.0*GeV;
LorentzMomentum momentumMissSum;
bool nonu = true;
for ( int i = 0, N = ptype.size(); i < N; ++i ) {
if ( invisibleParticles().size() == 0 ) {
if ( matcher()->check(*ptype[i]) ) {
// ptMissSum = ptMissSum + p[i].perp();
momentumMissSum = momentumMissSum + p[i];
nonu = false;
}
}
else if ( invisibleParticles().size() != 0 ) {
for ( vector<int>::const_iterator iID = invisibleParticles().begin(); iID != invisibleParticles().end(); ++iID ) {
int iInt = *iID;
if ( abs(ptype[i]->id())==iInt ) {
// ptMissSum = ptMissSum + p[i].perp();
momentumMissSum = momentumMissSum + p[i];
nonu = false;
}
}
}
}
if ( nonu ) return true;
Energy ptMiss = momentumMissSum.perp();
double weight = 1.0;
// if ( !parent->isInside<CutTypes::Momentum>(ptMissSum,ptMissMin(),ptMissMax(),weight) ) {
if ( !parent->isInside<CutTypes::Momentum>(ptMiss,ptMissMin(),ptMissMax(),weight) ) {
parent->lastCutWeight(0.0);
return false;
}
parent->lastCutWeight(weight);
return true;
}
string MissingPtCut::doInvisibleParticles(string in) {
istringstream ins(in);
int first;
ins >> first;
theInvisibleParticles.push_back(first);
return "";
}
void MissingPtCut::describe() const {
CurrentGenerator::log()
<< "MissingPtCut '" << name() << "' matching "
<< "'" << matcher()->name() << "'";
CurrentGenerator::log() << " within:\n";
CurrentGenerator::log()
<< "ptMiss = " << ptMissMin()/GeV << " .. " << ptMissMax()/GeV << " GeV\n";
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MissingPtCut::persistentOutput(PersistentOStream & os) const {
// os << ounit(thePtMissMin,GeV) << ounit(thePtMissMax,GeV);
os << ounit(thePtMissMin,GeV) << ounit(thePtMissMax,GeV)
<< theInvisibleParticles << theMatcher;
}
void MissingPtCut::persistentInput(PersistentIStream & is, int) {
// is >> iunit(thePtMissMin,GeV) >> iunit(thePtMissMax,GeV);
is >> iunit(thePtMissMin,GeV) >> iunit(thePtMissMax,GeV)
>> theInvisibleParticles >> theMatcher;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MissingPtCut,MultiCutBase>
describeHerwigMissingPtCut("Herwig::MissingPtCut", "HwMatchboxCuts.so");
void MissingPtCut::Init() {
static ClassDocumentation<MissingPtCut> documentation
// ("MissingPtCut implements a cut on the missing transverse momentum "
// "of a set of outgoing particles, i.e. for now the total transverse momentum "
// "of all outgoing neutrinos in an event.");
("MissingPtCut implements a cut on the transverse momentum of the four-momentum "
"sum of a set of outgoing particles that cannot be detected. By default the three "
"standard model neutrinos are considered. If at least one undetectable particle "
"is specified through the InvisibleParticles interface, the default choice is "
"nullified.");
static Command<MissingPtCut> interfaceInvisibleParticles
("InvisibleParticles",
"Insert the PDG code of a particle that cannot be detected. If no particle "
"is inserted at all, the three standard model neutrinos are considered by "
"default. If at least one particle is inserted, the default choice is nullified.",
&MissingPtCut::doInvisibleParticles, false);
static Parameter<MissingPtCut,Energy> interfacePtMissMin
("PtMissMin",
"The minimum missing pt required.",
&MissingPtCut::thePtMissMin, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<MissingPtCut,Energy> interfacePtMissMax
("PtMissMax",
"The maximum missing pt allowed.",
&MissingPtCut::thePtMissMax, GeV, Constants::MaxEnergy, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Reference<MissingPtCut,MatcherBase> interfaceMatcher
("Matcher",
"A matcher for particles to cut on.",
&MissingPtCut::theMatcher, false, false, true, false, false);
}
diff --git a/MatrixElement/Matchbox/Cuts/MissingPtCut.h b/MatrixElement/Matchbox/Cuts/MissingPtCut.h
--- a/MatrixElement/Matchbox/Cuts/MissingPtCut.h
+++ b/MatrixElement/Matchbox/Cuts/MissingPtCut.h
@@ -1,188 +1,180 @@
// -*- C++ -*-
//
// MissingPtCut.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MissingPtCut_H
#define Herwig_MissingPtCut_H
//
// This is the declaration of the MissingPtCut class.
//
#include "ThePEG/Cuts/MultiCutBase.h"
#include "ThePEG/PDT/MatcherBase.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Christian Reuschle
*
* \brief MissingPtCut implements a cut on the total missing transverse momentum of a set of outgoing particles, i.e. for now the total transverse momentum of all outgoing neutrinos in an event.
*
* @see \ref MissingPtCutInterfaces "The interfaces"
* defined for MissingPtCut.
*/
class MissingPtCut: public MultiCutBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MissingPtCut();
- /**
- * The destructor.
- */
- virtual ~MissingPtCut();
- //@}
-
public:
/** @name Virtual functions to be overridden by sub-classes. */
//@{
/**
* Return the minimum allowed value of the squared invariant mass of
* a set of outgoing partons of the given types. Typically used to
* cut off the tails of the mass of a resonance for efficiency.
*/
virtual Energy2 minS(const tcPDVector) const { return ZERO; }
/**
* Return the maximum allowed value of the squared invariant mass of
* a set of outgoing partons of the given types. Typically used to
* cut off the tails of the mass of a resonance for efficiency.
*/
virtual Energy2 maxS(const tcPDVector) const { return Constants::MaxEnergy2; }
/**
* Return true if a set of outgoing particles with type \a ptype
* and corresponding momenta \a p passes the cuts.
*/
virtual bool passCuts(tcCutsPtr parent, const tcPDVector & ptype,
const vector<LorentzMomentum> & p) const;
/**
* Describe the currently active cuts in the log file.
*/
virtual void describe() const;
/**
* Return the matcher for particles to cut on.
*/
Ptr<MatcherBase>::tptr matcher() const { return theMatcher; }
//@}
public:
/**
* Return the PDG codes of those particles that cannot be detected
*/
const vector<int>& invisibleParticles() const { return theInvisibleParticles; }
/**
* Command to insert the PDG code of a particle that cannot be detected
*/
string doInvisibleParticles(string);
/**
* Return the minimum missing pt.
*/
Energy ptMissMin() const { return thePtMissMin; }
/**
* Return the maximum missing pt.
*/
Energy ptMissMax() const { return thePtMissMax; }
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The PDG codes of those particles that cannot be detected
*/
vector<int> theInvisibleParticles;
/**
* The minimum missing pt.
*/
Energy thePtMissMin;
/**
* The maximum missing pt.
*/
Energy thePtMissMax;
/**
* A matcher for particles to cut on.
*/
Ptr<MatcherBase>::ptr theMatcher;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MissingPtCut & operator=(const MissingPtCut &) = delete;
};
}
#endif /* Herwig_MissingPtCut_H */
diff --git a/MatrixElement/Matchbox/Cuts/PairRapidityCut.cc b/MatrixElement/Matchbox/Cuts/PairRapidityCut.cc
--- a/MatrixElement/Matchbox/Cuts/PairRapidityCut.cc
+++ b/MatrixElement/Matchbox/Cuts/PairRapidityCut.cc
@@ -1,302 +1,300 @@
// -*- C++ -*-
//
// PairRapidityCut.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 PairRapidityCut class.
//
#include "PairRapidityCut.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/CurrentGenerator.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/PDT/ParticleData.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/PDT/MatcherBase.h"
#include "ThePEG/PDT/StandardMatchers.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
void PairRapidityCut::describe() const {
CurrentGenerator::log()
<< fullName() << "\n"
<< "matching between: '"
<< theFirstMatcher->name() << "' and '"
// << theSecondMatcher->name() << "':\n"
<< theSecondMatcher->name() << "':\n";
// << "y = " << theMinRapidity << " .. " << theMaxRapidity << "\n"
for ( vector<pair<double,double> >::const_iterator r = yRanges().begin();
r != yRanges().end(); ++r ) {
CurrentGenerator::log() << "y = " << r->first << " .. " << r->second << "\n";
}
// << "same flavour only = " << (theSameFlavourOnly?"Yes":"No") << " \n"
CurrentGenerator::log()
<< "same flavour only = " << (theSameFlavourOnly?"Yes":"No") << " \n"
<< "opposite sign only = " << (theOppositeSignOnly?"Yes":"No") << " \n\n";
}
PairRapidityCut::PairRapidityCut()
: thePseudo(false), theSameFlavourOnly(false), theOppositeSignOnly(false) {}
-PairRapidityCut::~PairRapidityCut() {}
-
IBPtr PairRapidityCut::clone() const {
return new_ptr(*this);
}
IBPtr PairRapidityCut::fullclone() const {
return new_ptr(*this);
}
bool PairRapidityCut::passCuts(tcCutsPtr parent, tcPDPtr pitype, tcPDPtr pjtype,
LorentzMomentum pi, LorentzMomentum pj,
bool inci, bool incj) const {
bool match = false;
if ( theFirstMatcher->check(*pitype) && theSecondMatcher->check(*pjtype) ) match = true;
if ( theFirstMatcher->check(*pjtype) && theSecondMatcher->check(*pitype) ) match = true;
// if ( !match ||
// ( theMinRapidity == -Constants::MaxRapidity && theMaxRapidity == Constants::MaxRapidity ) ) return true;
if ( !match || theYRanges.empty() ) return true;
if ( inci || incj ) return true;
if ( sameFlavourOnly() || oppositeSignOnly() ) {
int fam1 = family(pitype->id());
int fam2 = family(pjtype->id());
if ( fam1 && fam2 ) {
if ( sameFlavourOnly() && ( abs(fam1) != abs(fam2) ) ) return true;
if ( oppositeSignOnly() && ( fam1*fam2 > 0 ) ) return true;
}
}
double weight = 1.0;
// double minv = (pi+pj).rapidity();
//
// if ( !parent->isInside<CutTypes::Rapidity>(minv,minRapidity(),maxRapidity(),weight) )
// {
// parent->lastCutWeight(0.0);
// return false;
// }
//// From IdentifiedParticleCut.cc
// double y = p.rapidity() + parent->currentYHat();
// for ( vector<pair<double,double> >::const_iterator dy = yRanges().begin();
// dy != yRanges().end(); ++dy ) {
// if ( !parent->isInside<CutTypes::Rapidity>(y,dy->first,dy->second,weight) ) {
// parent->lastCutWeight(0.0);
// return false;
// }
// }
double y = (pi+pj).rapidity() + parent->currentYHat();
// Actually, why not
// double y = (pi+pj).rapidity() + parent->currentYHat() + parent->Y();
// as in ThePEG /Cuts/Cuts.cc, /Cuts/OneCutBase.cc, etc. ???
for ( vector<pair<double,double> >::const_iterator dy = yRanges().begin();
dy != yRanges().end(); ++dy ) {
if (!thePseudo) {
if ( !parent->isInside<CutTypes::Rapidity>(y,dy->first,dy->second,weight) ) {
parent->lastCutWeight(0.0);
return false;
}
} else if (thePseudo) {
//// From ThePEG/Cuts/OneCutBase or ThePEG/Cuts/SimpleKTCut
// if ( p.mt()*sinh(y) <= p.perp()*sinh(theMinEta) ) return false;
// if ( p.mt()*sinh(y) >= p.perp()*sinh(theMaxEta) ) return false;
if ( !parent->isInside<CutTypes::Rapidity>( (pi+pj).mt()*sinh(y)/GeV ,
(pi+pj).perp()*sinh(dy->first)/GeV ,
(pi+pj).perp()*sinh(dy->second)/GeV ,
weight) ) {
parent->lastCutWeight(0.0);
return false;
}
}
}
parent->lastCutWeight(weight);
return true;
}
int PairRapidityCut::family(long id) const {
int sign = (id>0)?-1:1;
switch ( id ) {
case ParticleID::u:
case ParticleID::ubar:
case ParticleID::d:
case ParticleID::dbar:
return 1*sign; break;
case ParticleID::c:
case ParticleID::cbar:
case ParticleID::s:
case ParticleID::sbar:
return 2*sign; break;
case ParticleID::t:
case ParticleID::tbar:
case ParticleID::b:
case ParticleID::bbar:
return 3*sign; break;
case ParticleID::eminus:
case ParticleID::eplus:
case ParticleID::nu_e:
case ParticleID::nu_ebar:
return 11*sign; break;
case ParticleID::muminus:
case ParticleID::muplus:
case ParticleID::nu_mu:
case ParticleID::nu_mubar:
return 12*sign; break;
case ParticleID::tauminus:
case ParticleID::tauplus:
case ParticleID::nu_tau:
case ParticleID::nu_taubar:
return 13*sign; break;
}
return 0;
}
string PairRapidityCut::doYRange(string in) {
istringstream ins(in);
double first, second;
ins >> first >> second;
if ( first > second )
swap(first,second);
theYRanges.push_back(make_pair(first,second));
return "";
}
void PairRapidityCut::persistentOutput(PersistentOStream & os) const {
// os << theMinRapidity << theMaxRapidity
os << theYRanges << thePseudo
<< theSameFlavourOnly << theOppositeSignOnly
<< theFirstMatcher << theSecondMatcher;
}
void PairRapidityCut::persistentInput(PersistentIStream & is, int) {
// is >> theMinRapidity >> theMaxRapidity
is >> theYRanges >> thePseudo
>> theSameFlavourOnly >> theOppositeSignOnly
>> theFirstMatcher >> theSecondMatcher;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<PairRapidityCut,TwoCutBase>
describeHerwigPairRapidityCut("Herwig::PairRapidityCut", "HwMatchboxCuts.so");
void PairRapidityCut::Init() {
static ClassDocumentation<PairRapidityCut> documentation
("This class implements a rapidity cut on lepton pairs of "
"final-state particles.");
// static Parameter<PairRapidityCut,double> interfaceMinRapidity
// ("MinRapidity",
// "The minimal allowed rapditiy of the particle pair ",
// &PairRapidityCut::theMinRapidity, -Constants::MaxRapidity, -Constants::MaxRapidity, Constants::MaxRapidity,
// false, false, Interface::limited);
//
// static Parameter<PairRapidityCut,double> interfaceMaxRapidity
// ("MaxRapidity",
// "The maximal allowed rapidity of the particle pair ",
// &PairRapidityCut::theMaxRapidity, Constants::MaxRapidity, -Constants::MaxRapidity, Constants::MaxRapidity,
// false, false, Interface::limited);
static Command<PairRapidityCut> interfaceYRange
("YRange",
"Insert a rapidity range.",
&PairRapidityCut::doYRange, false);
static Switch<PairRapidityCut,bool> interfacePseudo
("Pseudo",
"Use pseudo rapidity instead of rapidity ",
&PairRapidityCut::thePseudo, false, false, false);
static SwitchOption interfacePseudoNo
(interfacePseudo,
"No",
"No",
false);
static SwitchOption interfacePseudoYes
(interfacePseudo,
"Yes",
"Yes",
true);
static Switch<PairRapidityCut,bool> interfaceSameFlavourOnly
("SameFlavourOnly",
"Whether cut works on fermion pairs of the same flavour only ",
&PairRapidityCut::theSameFlavourOnly, true, false, false);
static SwitchOption interfaceSameFlavourOnlyYes
(interfaceSameFlavourOnly,
"Yes",
"Yes",
true);
static SwitchOption interfaceSameFlavourOnlyNo
(interfaceSameFlavourOnly,
"No",
"No",
false);
static Switch<PairRapidityCut,bool> interfaceOppositeSignOnly
("OppositeSignOnly",
"Whether cut works on fermion pairs of opposite sign only ",
&PairRapidityCut::theOppositeSignOnly, true, false, false);
static SwitchOption interfaceOppositeSignOnlyYes
(interfaceOppositeSignOnly,
"Yes",
"Yes",
true);
static SwitchOption interfaceOppositeSignOnlyNo
(interfaceOppositeSignOnly,
"No",
"No",
false);
static Reference<PairRapidityCut,MatcherBase> interfaceFirstMatcher
("FirstMatcher",
"Matcher for first particle of type pitype in the pair (pitype,pjtype). "
"Only particles matching this object will be affected by the cut. ",
&PairRapidityCut::theFirstMatcher, true, false, true, true, false);
static Reference<PairRapidityCut,MatcherBase> interfaceSecondMatcher
("SecondMatcher",
"Matcher for second particle of type pjtype in the pair (pitype,pjtype). "
"Only particles matching this object will be affected by the cut. ",
&PairRapidityCut::theSecondMatcher, true, false, true, true, false);
}
diff --git a/MatrixElement/Matchbox/Cuts/PairRapidityCut.h b/MatrixElement/Matchbox/Cuts/PairRapidityCut.h
--- a/MatrixElement/Matchbox/Cuts/PairRapidityCut.h
+++ b/MatrixElement/Matchbox/Cuts/PairRapidityCut.h
@@ -1,242 +1,234 @@
// -*- C++ -*-
//
// PairRapidityCut.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_PairRapidityCut_H
#define Herwig_PairRapidityCut_H
//
// This is the declaration of the PairRapidityCut class.
//
#include "ThePEG/Cuts/TwoCutBase.h"
#include "ThePEG/PDT/MatcherBase.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Christian Reuschle
*
* \brief This class implements a cut on the rapidity of a pair of particles
*
* @see \ref PairRapidityCutInterfaces "The interfaces"
* defined for PairRapidityCut.
*/
class PairRapidityCut: public TwoCutBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
PairRapidityCut();
- /**
- * The destructor.
- */
- virtual ~PairRapidityCut();
- //@}
-
public:
/** @name Overridden virtual functions defined in the base class. */
//@{
/**
* Return true if a pair of particles with type \a pitype and \a
* pjtype and momenta \a pi and \a pj respectively passes the
* cuts. \a inci and \a inj indicates if the corresponding particles
* are incoming.
*/
virtual bool passCuts(tcCutsPtr parent, tcPDPtr pitype, tcPDPtr pjtype,
LorentzMomentum pi, LorentzMomentum pj,
bool inci = false, bool incj = false) const;
/**
* Return the minimum allowed squared invariant mass of two outgoing
* partons of type \a pi and \a pj.
*/
virtual Energy2 minSij(tcPDPtr , tcPDPtr ) const { return ZERO; }
/**
* Return the minimum allowed value of the negative of the squared
* invariant mass of an incoming parton of type \a pi and an
* outgoing parton of type \a po.
*/
virtual Energy2 minTij(tcPDPtr , tcPDPtr ) const { return ZERO; }
/**
* Return the minimum allowed value of \f$\Delta
* R_{ij}=\sqrt{\Delta\eta_{ij}^2+\Delta\phi_{ij}^2}\f$ of two
* outgoing partons of type \a pi and \a pj.
*/
virtual double minDeltaR(tcPDPtr , tcPDPtr ) const { return ZERO; }
/**
* Return the minimum allowed value of the longitudinally invariant
* \f$k_\perp\f$-algorithms distance measure. This is defined as
* \f$\min(p_{\perp i}, p_{\perp
* j})\sqrt{\Delta\eta_{ij}^2+\Delta\phi_{ij}^2}\f$ for two outgoing
* partons, or simply \f$p_{\perp i}\f$ or \f$p_{\perp j}\f$ for a
* single outgoing parton. Returns 0 if both partons are incoming. A
* null pointer indicates an incoming parton, hence the type of the
* incoming parton is irrelevant.
*/
virtual Energy minKTClus(tcPDPtr , tcPDPtr ) const { return ZERO; }
/**
* Return the minimum allowed value of the Durham
* \f$k_\perp\f$-algorithms distance measure. This is defined as
* \f$2\min(E_j^2, E_j^2)(1-\cos\theta_{ij})/\hat{s}\f$ for two
* outgoing partons.
*/
virtual double minDurham(tcPDPtr , tcPDPtr ) const { return ZERO; }
//@}
/**
* Describe the currently active cuts in the log file.
*/
virtual void describe() const;
public:
// /**
// * Return the minimal allowed rapidity
// */
// double minRapidity() const { return theMinRapidity; }
//
// /**
// * Return the maximal allowed rapidity
// */
// double maxRapidity() const { return theMaxRapidity; }
/**
* Return the rapidity ranges.
*/
const vector<pair<double,double> >& yRanges() const { return theYRanges; }
/**
* Return whether cut acts on same-flavour fermions only
*/
bool sameFlavourOnly() const { return theSameFlavourOnly; }
/**
* Return whether cut acts on opposite-sign fermions only
*/
bool oppositeSignOnly() const { return theOppositeSignOnly; }
/**
* Return the matchers for a pair of particles to cut on.
* Only a pair of particles, matching these objects, will be affected.
*/
Ptr<MatcherBase>::tptr firstMatcher() const { return theFirstMatcher; }
Ptr<MatcherBase>::tptr secondMatcher() const { return theSecondMatcher; }
protected:
/**
* Return the family of the given PDG id number.
*/
int family(long id) const;
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
private:
/**
* Command to insert a rapidity range
*/
string doYRange(string);
/**
* The rapidity ranges.
*/
vector<pair<double,double> > theYRanges;
/**
* Whether to use pseudo rapidity instead of rapidity
*/
bool thePseudo;
/**
* Whether the cut is active on same-flavour fermions only
* (ignored for pairs not consisting of two fermions)
*/
bool theSameFlavourOnly;
/**
* Whether the cut is active on opposite-sign fermions only
* (ignored for pairs not consisting of two fermions)
*/
bool theOppositeSignOnly;
/**
* Matchers for a pair of particles to cut on. Only a pair
* of particles, matching these objects, will be affected.
*/
Ptr<MatcherBase>::ptr theFirstMatcher;
Ptr<MatcherBase>::ptr theSecondMatcher;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
PairRapidityCut & operator=(const PairRapidityCut &) = delete;
};
}
#endif /* Herwig_PairRapidityCut_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FFMggxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFMggxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FFMggxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FFMggxDipole.cc
@@ -1,150 +1,148 @@
// -*- C++ -*-
//
// FFMggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FFMggxDipole class.
//
#include "FFMggxDipole.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/FFMassiveTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h"
using namespace Herwig;
FFMggxDipole::FFMggxDipole()
: SubtractionDipole() {}
-FFMggxDipole::~FFMggxDipole() {}
-
IBPtr FFMggxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FFMggxDipole::fullclone() const {
return new_ptr(*this);
}
bool FFMggxDipole::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 FFMggxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
// masses, g->gg all masses zero except spectator
double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() );
// massive extra terms, viji = 1
double vijk = sqrt( sqr(2.*muj2+(1.-muj2)*(1.-y))-4.*muj2 ) / ((1.-muj2)*(1.-y));
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
double zp = 0.5*(1.+vijk);
double zm = 0.5*(1.-vijk);
double res = -ccme2;
// extra mass terms all = 0.
res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= (1./(1-z*(1-y))+1./(1-(1.-z)*(1.-y))+(z*(1.-z)-zm*zp-2.)/vijk);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
double FFMggxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
// masses, g->gg all masses zero except spectator
double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() );
// massive extra terms
double vijk = sqrt( sqr(2.*muj2+(1.-muj2)*(1.-y))-4.*muj2 ) / ((1.-muj2)*(1.-y));
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./vijk; // kappa=0
double zim = z-0.5*(1.-vijk), zjm = (1.-z)-0.5*(1.-vijk);
Lorentz5Momentum pc =
zim*realEmissionME()->lastXComb().meMomenta()[realEmitter()] -
zjm*realEmissionME()->lastXComb().meMomenta()[realEmission()];
SpinCorrelationTensor corr(-diag,pc,prop/2.*vijk);
double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),
corr);
// extra mass terms all = 0.
res *= 16.*Constants::pi*SM().Nc()*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void FFMggxDipole::persistentOutput(PersistentOStream &) const {
}
void FFMggxDipole::persistentInput(PersistentIStream &, int) {
}
void FFMggxDipole::Init() {
static ClassDocumentation<FFMggxDipole> documentation
("FFMggxDipole");
DipoleRepository::registerDipole<0,FFMggxDipole,FFMassiveTildeKinematics,FFMassiveInvertedTildeKinematics>
("FFMggxDipole","FFMassiveTildeKinematics","FFMassiveInvertedTildeKinematics");
}
// *** 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<FFMggxDipole,SubtractionDipole>
describeHerwigFFMggxDipole("Herwig::FFMggxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FFMggxDipole.h b/MatrixElement/Matchbox/Dipoles/FFMggxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FFMggxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FFMggxDipole.h
@@ -1,166 +1,158 @@
// -*- C++ -*-
//
// FFMggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFMggxDipole_H
#define HERWIG_FFMggxDipole_H
//
// This is the declaration of the FFMggxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Martin Stoll
*
* \brief FFMggxDipole implements the D_{g,g;k} subtraction dipole.
*
*/
class FFMggxDipole: public SubtractionDipole {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFMggxDipole();
- /**
- * The destructor.
- */
- virtual ~FFMggxDipole();
- //@}
-
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;
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.
*/
FFMggxDipole & operator=(const FFMggxDipole &) = delete;
};
}
#endif /* HERWIG_FFMggxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.cc
@@ -1,156 +1,154 @@
// -*- C++ -*-
//
// FFMqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FFMqgxDipole class.
//
#include "FFMqgxDipole.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/FFMassiveTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h"
using namespace Herwig;
FFMqgxDipole::FFMqgxDipole()
: SubtractionDipole() {}
-FFMqgxDipole::~FFMqgxDipole() {}
-
IBPtr FFMqgxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FFMqgxDipole::fullclone() const {
return new_ptr(*this);
}
bool FFMqgxDipole::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()) < 7 &&
( abs(partons[emitter]->id()) < 7 || abs(partons[emitter]->id()) == 1000021 ) &&
!(partons[emitter]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO);
}
double FFMqgxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
// masses
double muQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass() / lastDipoleScale() );
double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() );
// massive extra terms
double vijk = sqrt( sqr(2.*muj2+(1.-muQ2-muj2)*(1.-y))-4.*muj2 ) / ((1.-muQ2-muj2)*(1.-y));
double vbar = sqrt( 1.+sqr(muQ2)+sqr(muj2)-2.*(muQ2+muj2+muQ2*muj2) ) / (1.-muQ2-muj2);
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
if ( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->id() == 1000021 )
CF = SM().Nc(); // For the SUSY D_{gluino,g;k} subtraction dipole we need to replace CF by CA=Nc
// extra mass terms cancel: mi2+m2-Mi2 = mQ2+0-mQ2
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= ( 2./(1.-z*(1.-y)) - vbar/vijk * ( (1.+z) + muQ2*sqr(lastDipoleScale())*2./prop ) );
res *= -ccme2;
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
double FFMqgxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
// masses
double muQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass() / lastDipoleScale() );
double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() );
// massive extra terms
double vijk = sqrt( sqr(2.*muj2+(1.-muQ2-muj2)*(1.-y))-4.*muj2 ) / ((1.-muQ2-muj2)*(1.-y));
double vbar = sqrt( 1.+sqr(muQ2)+sqr(muj2)-2.*(muQ2+muj2+muQ2*muj2) ) / (1.-muQ2-muj2);
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
if ( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->id() == 1000021 )
CF = SM().Nc(); // For the SUSY D_{gluino,g;k} subtraction dipole we need to replace CF by CA=Nc
// extra mass terms cancel: mi2+m2-Mi2 = mQ2+0-mQ2
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= ( 2./(1.-z*(1.-y)) - vbar/vijk * ( (1.+z) + muQ2*sqr(lastDipoleScale())*2./prop ) );
res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()));
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void FFMqgxDipole::persistentOutput(PersistentOStream &) const {
}
void FFMqgxDipole::persistentInput(PersistentIStream &, int) {
}
void FFMqgxDipole::Init() {
static ClassDocumentation<FFMqgxDipole> documentation
("FFMqgxDipole");
DipoleRepository::registerDipole<0,FFMqgxDipole,FFMassiveTildeKinematics,FFMassiveInvertedTildeKinematics>
("FFMqgxDipole","FFMassiveTildeKinematics","FFMassiveInvertedTildeKinematics");
}
// *** 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<FFMqgxDipole,SubtractionDipole>
describeHerwigFFMqgxDipole("Herwig::FFMqgxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FFMqgxDipole.h
@@ -1,161 +1,153 @@
// -*- C++ -*-
//
// FFMqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFMqgxDipole_H
#define HERWIG_FFMqgxDipole_H
//
// This is the declaration of the FFMqgxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Martin Stoll, Christian Reuschle
*
* \brief FFMqgxDipole implements the D_{Q,g;k} subtraction dipole,
* as well as the D_{gluino,g;k} subtraction dipole.
*
*/
class FFMqgxDipole: public SubtractionDipole {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFMqgxDipole();
- /**
- * The destructor.
- */
- virtual ~FFMqgxDipole();
- //@}
-
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;
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.
*/
FFMqgxDipole & operator=(const FFMqgxDipole &) = delete;
};
}
#endif /* HERWIG_FFMqgxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.cc
@@ -1,159 +1,157 @@
// -*- C++ -*-
//
// FFMqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FFMqqxDipole class.
//
#include "FFMqqxDipole.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/FFMassiveTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h"
using namespace Herwig;
FFMqqxDipole::FFMqqxDipole()
: SubtractionDipole() {}
-FFMqqxDipole::~FFMqqxDipole() {}
-
IBPtr FFMqqxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FFMqqxDipole::fullclone() const {
return new_ptr(*this);
}
bool FFMqqxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter > 1 && spectator > 1 &&
abs(partons[emission]->id()) < 7 &&
abs(partons[emitter]->id()) < 7 &&
partons[emission]->id() + partons[emitter]->id() == 0 &&
!(partons[emission]->hardProcessMass() == ZERO &&
partons[emitter]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO);
}
double FFMqqxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
// masses
double muQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass() / lastDipoleScale() );
double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() );
Energy2 mQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass() );
// massive extra terms
double t = 1.-2.*muQ2-muj2;
double vijk = sqrt( sqr(2.*muj2+t*(1.-y))-4.*muj2 ) / (t*(1.-y));
double viji = sqrt( sqr(t*y) - 4.*sqr(muQ2) ) / ( t*y + 2.*muQ2);
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
double zp = 0.5*(1.+viji*vijk);
double zm = 0.5*(1.-viji*vijk);
// kappa=0 -- otherwise: extra term
double res = -ccme2;
res *= (1.-2.*(z*(1-z)-zp*zm));
res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/ ((prop+2.*mQ2)*vijk);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
double FFMqqxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
// masses
double muQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass() / lastDipoleScale() );
double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() );
Energy2 mQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass() );
// massive extra terms
double vijk = sqrt( sqr(2.*muj2+(1.-2.*muQ2-muj2)*(1.-y))-4.*muj2 ) / ((1.-2.*muQ2-muj2)*(1.-y));
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
double zim = z-0.5*(1.-vijk), zjm = (1.-z)-0.5*(1.-vijk);
Lorentz5Momentum pc =
zim*realEmissionME()->lastXComb().meMomenta()[realEmitter()] -
zjm*realEmissionME()->lastXComb().meMomenta()[realEmission()];
// kappa=0 -- otherwise: extra diagonal term (instead of just -1.)
SpinCorrelationTensor corr(-1.,pc,-(prop+2.*mQ2)/4.);
double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),
corr);
res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/ ((prop+2.*mQ2)*vijk);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void FFMqqxDipole::persistentOutput(PersistentOStream &) const {
}
void FFMqqxDipole::persistentInput(PersistentIStream &, int) {
}
void FFMqqxDipole::Init() {
static ClassDocumentation<FFMqqxDipole> documentation
("FFMqqxDipole");
DipoleRepository::registerDipole<0,FFMqqxDipole,FFMassiveTildeKinematics,FFMassiveInvertedTildeKinematics>
("FFMqqxDipole","FFMassiveTildeKinematics","FFMassiveInvertedTildeKinematics");
}
// *** 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<FFMqqxDipole,SubtractionDipole>
describeHerwigFFMqqxDipole("Herwig::FFMqqxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.h b/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FFMqqxDipole.h
@@ -1,168 +1,160 @@
// -*- C++ -*-
//
// FFMqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFMqqxDipole_H
#define HERWIG_FFMqqxDipole_H
//
// This is the declaration of the FFMqqxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Martin Stoll
*
* \brief FFMqqxDipole implements the D_{q,qbar;k} subtraction dipole.
*
*/
class FFMqqxDipole: public SubtractionDipole {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFMqqxDipole();
- /**
- * The destructor.
- */
- virtual ~FFMqqxDipole();
- //@}
-
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;
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.
*/
FFMqqxDipole & operator=(const FFMqqxDipole &) = delete;
};
}
#endif /* HERWIG_FFMqqxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.cc
@@ -1,152 +1,150 @@
// -*- C++ -*-
//
// FFMsqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FFMsqgxDipole class.
//
#include "FFMsqgxDipole.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/FFMassiveTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h"
using namespace Herwig;
FFMsqgxDipole::FFMsqgxDipole()
: SubtractionDipole() {}
-FFMsqgxDipole::~FFMsqgxDipole() {}
-
IBPtr FFMsqgxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FFMsqgxDipole::fullclone() const {
return new_ptr(*this);
}
bool FFMsqgxDipole::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())> 1000000 && abs(partons[emitter]->id())< 1000007) ||
(abs(partons[emitter]->id())> 2000000 && abs(partons[emitter]->id())< 2000007)) &&
!(partons[emitter]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() == ZERO);
}
double FFMsqgxDipole::me2Avg(double ccme2) const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
// masses
double muSQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass() / lastDipoleScale() );
double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() );
// massive extra terms
double vijk = sqrt( sqr(2.*muj2+(1.-muSQ2-muj2)*(1.-y))-4.*muj2 ) / ((1.-muSQ2-muj2)*(1.-y));
double vbar = sqrt( 1.+sqr(muSQ2)+sqr(muj2)-2.*(muSQ2+muj2+muSQ2*muj2) ) / (1.-muSQ2-muj2);
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)) - vbar/vijk * ( 2. + muSQ2*sqr(lastDipoleScale())*2./prop ));
res *= -ccme2;
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
double FFMsqgxDipole::me2() const {
if ( jacobian() == 0.0 )
return 0.0;
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
// masses
double muSQ2 = sqr( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass() / lastDipoleScale() );
double muj2 = sqr( realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass() / lastDipoleScale() );
// massive extra terms
double vijk = sqrt( sqr(2.*muj2+(1.-muSQ2-muj2)*(1.-y))-4.*muj2 ) / ((1.-muSQ2-muj2)*(1.-y));
double vbar = sqrt( 1.+sqr(muSQ2)+sqr(muj2)-2.*(muSQ2+muj2+muSQ2*muj2) ) / (1.-muSQ2-muj2);
Energy2 prop =
2.*((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realEmission()]));
double CF = (SM().Nc()*SM().Nc()-1.)/(2.*SM().Nc());
// extra mass terms cancel: mi2+m2-Mi2 = mQ2+0-mQ2
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
res *= ( 2./(1.-z*(1.-y)) - vbar/vijk * ( 2. + muSQ2*sqr(lastDipoleScale())*2./prop ) );
res *= -underlyingBornME()->colourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()));
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void FFMsqgxDipole::persistentOutput(PersistentOStream &) const {
}
void FFMsqgxDipole::persistentInput(PersistentIStream &, int) {
}
void FFMsqgxDipole::Init() {
static ClassDocumentation<FFMsqgxDipole> documentation
("FFMsqgxDipole");
DipoleRepository::registerDipole<0,FFMsqgxDipole,FFMassiveTildeKinematics,FFMassiveInvertedTildeKinematics>
("FFMsqgxDipole","FFMassiveTildeKinematics","FFMassiveInvertedTildeKinematics");
}
// *** 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<FFMsqgxDipole,SubtractionDipole>
describeHerwigFFMsqgxDipole("Herwig::FFMsqgxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FFMsqgxDipole.h
@@ -1,164 +1,156 @@
// -*- C++ -*-
//
// FFMsqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFMsqgxDipole_H
#define HERWIG_FFMsqgxDipole_H
//
// This is the declaration of the FFMsqgxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Alexandra Wilcock, Christian Reuschle
*
* \brief FFMsqgxDipole implements the D_{sq,g;k} subtraction dipole.
*
*/
class FFMsqgxDipole: public SubtractionDipole {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFMsqgxDipole();
- /**
- * The destructor.
- */
- virtual ~FFMsqgxDipole();
- //@}
-
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(abs(partons[emitter]->id()) - 1000000) < 7 || abs(abs(partons[emitter]->id()) - 2000000) < 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;
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.
*/
FFMsqgxDipole & operator=(const FFMsqgxDipole &) = delete;
};
}
#endif /* HERWIG_FFMsqgxDipole_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,138 +1,136 @@
// -*- C++ -*-
//
// FFggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,167 +1,159 @@
// -*- C++ -*-
//
// FFggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#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,137 +1,135 @@
// -*- C++ -*-
//
// FFqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,160 +1,152 @@
// -*- C++ -*-
//
// FFqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#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,138 +1,136 @@
// -*- C++ -*-
//
// FFqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,168 +1,160 @@
// -*- C++ -*-
//
// FFqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#endif /* HERWIG_FFqqxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.cc
@@ -1,167 +1,165 @@
// -*- C++ -*-
//
// FIqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FIMqgxDipole class.
//
#include "FIMqgxDipole.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"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h"
using namespace Herwig;
FIMqgxDipole::FIMqgxDipole()
: SubtractionDipole() {}
-FIMqgxDipole::~FIMqgxDipole() {}
-
IBPtr FIMqgxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FIMqgxDipole::fullclone() const {
return new_ptr(*this);
}
bool FIMqgxDipole::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()) < 7 &&
( abs(partons[emitter]->id()) < 7 || abs(partons[emitter]->id()) == 1000021 ) &&
partons[emitter]->hardProcessMass() != ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double FIMqgxDipole::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());
if ( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->id() == 1000021 )
CF = SM().Nc(); // For the SUSY D_{gluino,g}^a subtraction dipole we need to replace CF by CA=Nc
// extra mass terms cancel
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
// NOTE: extra term taken from FIqgxDipole implementation
// NOTE: extra term switched off for the moment in the massive case
res *= (
2./(1.-z+(1.-x)) - (1.+z)
// + (1.-x)*(1.+3.*x*z)
- sqr(realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass()) / prop * 2.*x
);
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
double FIMqgxDipole::me2() 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());
if ( realEmissionME()->lastXComb().mePartonData()[realEmitter()]->id() == 1000021 )
CF = SM().Nc(); // For the SUSY D_{gluino,g}^a subtraction dipole we need to replace CF by CA=Nc
// extra mass terms cancel
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
// NOTE: extra term taken from FIqgxDipole implementation
// NOTE: extra term switched off for the moment in the massive case
res *= (
2./(1.-z+(1.-x)) - (1.+z)
// + (1.-x)*(1.+3.*x*z)
- sqr(realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass()) / prop * 2.*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 FIMqgxDipole::persistentOutput(PersistentOStream &) const {
}
void FIMqgxDipole::persistentInput(PersistentIStream &, int) {
}
void FIMqgxDipole::Init() {
static ClassDocumentation<FIMqgxDipole> documentation
("FIMqgxDipole");
// DipoleRepository::registerDipole<0,FIMqgxDipole,FILightTildeKinematics,FILightInvertedTildeKinematics>
// ("FIMqgxDipole","FILightTildeKinematics","FILightInvertedTildeKinematics");
DipoleRepository::registerDipole<0,FIMqgxDipole,FIMassiveTildeKinematics,FIMassiveInvertedTildeKinematics>
("FIMqgxDipole","FIMassiveTildeKinematics","FIMassiveInvertedTildeKinematics");
}
// *** 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<FIMqgxDipole,SubtractionDipole>
describeHerwigFIMqgxDipole("Herwig::FIMqgxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FIMqgxDipole.h
@@ -1,161 +1,153 @@
// -*- C++ -*-
//
// FIMqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FIMqgxDipole_H
#define HERWIG_FIMqgxDipole_H
//
// This is the declaration of the FIMqgxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Chrstian Reuschle
*
* \brief FIMqgxDipole implements the D_{Q,g}^a subtraction dipole,
* as well as the D_{gluino,g}^a subtraction dipole.
*
*/
class FIMqgxDipole: public SubtractionDipole {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIMqgxDipole();
- /**
- * The destructor.
- */
- virtual ~FIMqgxDipole();
- //@}
-
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;
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.
*/
FIMqgxDipole & operator=(const FIMqgxDipole &) = delete;
};
}
#endif /* HERWIG_FIMqgxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.cc
@@ -1,163 +1,161 @@
// -*- C++ -*-
//
// FIMqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 "FIMqqxDipole.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/FIMassiveTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h"
using namespace Herwig;
FIMqqxDipole::FIMqqxDipole()
: SubtractionDipole() {}
-FIMqqxDipole::~FIMqqxDipole() {}
-
IBPtr FIMqqxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FIMqqxDipole::fullclone() const {
return new_ptr(*this);
}
bool FIMqqxDipole::canHandle(const cPDVector& partons,
int emitter, int emission, int spectator) const {
return
emitter > 1 && spectator < 2 &&
abs(partons[emission]->id()) < 7 &&
abs(partons[emitter]->id()) < 7 &&
partons[emission]->id() + partons[emitter]->id() == 0 &&
// !(partons[emitter]->hardProcessMass() == ZERO &&
// partons[emission]->hardProcessMass() == ZERO &&
// partons[spectator]->hardProcessMass() == ZERO);
!(partons[emitter]->hardProcessMass() == ZERO &&
partons[emission]->hardProcessMass() == ZERO) &&
partons[spectator]->hardProcessMass() == ZERO;
}
double FIMqqxDipole::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;
Energy2 mQ2 = sqr(realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass());
// double muQ2 = x * mQ2 /
double muQ2 = 0.5 * z * mQ2 /
((realEmissionME()->lastXComb().meMomenta()[realEmitter()])*
(realEmissionME()->lastXComb().meMomenta()[realSpectator()]));
// mu_ij=0, mu_i=mu_j=mu_Q.
// double zm = ( 1.-x - sqrt( sqr(1.-x-2.*muQ2) - 4.*muQ2 ) ) / ( 2.*(1.-x) );
// double zp = ( 1.-x + sqrt( sqr(1.-x-2.*muQ2) - 4.*muQ2 ) ) / ( 2.*(1.-x) );
double zm = ( 1.-x - sqrt( sqr(1.-x-2.*muQ2) - 4.*sqr(muQ2) ) ) / ( 2.*(1.-x) );
double zp = ( 1.-x + sqrt( sqr(1.-x-2.*muQ2) - 4.*sqr(muQ2) ) ) / ( 2.*(1.-x) );
double res = 1.-2.*(z-zm)*(zp-z);
res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/( prop+2.*mQ2*x );
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
double FIMqqxDipole::me2() 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;
Energy2 mQ2 = sqr((realEmissionME()->lastXComb().mePartonData()[realEmitter()])->hardProcessMass());
Lorentz5Momentum pc =
z*realEmissionME()->lastXComb().meMomenta()[realEmitter()] -
(1.-z)*realEmissionME()->lastXComb().meMomenta()[realEmission()];
SpinCorrelationTensor corr(-1.,pc,-(prop+2.*mQ2*x)/(4.*x));
double res = -underlyingBornME()->spinColourCorrelatedME2(make_pair(bornEmitter(),bornSpectator()),
corr);
res *= 4.*Constants::pi*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/( prop+2.*mQ2*x );
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
void FIMqqxDipole::persistentOutput(PersistentOStream &) const {
}
void FIMqqxDipole::persistentInput(PersistentIStream &, int) {
}
void FIMqqxDipole::Init() {
static ClassDocumentation<FIMqqxDipole> documentation
("FIMqqxDipole");
// DipoleRepository::registerDipole<0,FIMqqxDipole,FILightTildeKinematics,FILightInvertedTildeKinematics>
// ("FIMqqxDipole","FILightTildeKinematics","FILightInvertedTildeKinematics");
DipoleRepository::registerDipole<0,FIMqqxDipole,FIMassiveTildeKinematics,FIMassiveInvertedTildeKinematics>
("FIMqqxDipole","FIMassiveTildeKinematics","FIMassiveInvertedTildeKinematics");
}
// *** 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<FIMqqxDipole,SubtractionDipole>
describeHerwigFIMqqxDipole("Herwig::FIMqqxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.h b/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FIMqqxDipole.h
@@ -1,168 +1,160 @@
// -*- C++ -*-
//
// FIMqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FIMqqxDipole_H
#define HERWIG_FIMqqxDipole_H
//
// This is the declaration of the FIMqqxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FIMqqxDipole implements the D_{q,qbar}^a subtraction dipole.
*
*/
class FIMqqxDipole: public SubtractionDipole {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIMqqxDipole();
- /**
- * The destructor.
- */
- virtual ~FIMqqxDipole();
- //@}
-
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;
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.
*/
FIMqqxDipole & operator=(const FIMqqxDipole &) = delete;
};
}
#endif /* HERWIG_FIMqqxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.cc
@@ -1,155 +1,153 @@
// -*- C++ -*-
//
// FIqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FIMsqgxDipole class.
//
#include "FIMsqgxDipole.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/FIMassiveTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h"
using namespace Herwig;
FIMsqgxDipole::FIMsqgxDipole()
: SubtractionDipole() {}
-FIMsqgxDipole::~FIMsqgxDipole() {}
-
IBPtr FIMsqgxDipole::clone() const {
return new_ptr(*this);
}
IBPtr FIMsqgxDipole::fullclone() const {
return new_ptr(*this);
}
bool FIMsqgxDipole::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())> 1000000 && abs(partons[emitter]->id())< 1000007) ||
(abs(partons[emitter]->id())> 2000000 && abs(partons[emitter]->id())< 2000007)) &&
partons[emitter]->hardProcessMass() != ZERO &&
partons[spectator]->hardProcessMass() == ZERO;
}
double FIMsqgxDipole::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());
// extra mass terms cancel
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
// // NOTE: extra term taken from FIqgxDipole implementation??
// res *= ( 2./(1.-z+(1.-x)) - 2. +(1.-x)*(1.+3.*x*z) -
// sqr(realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass()) / prop * 2.*x);
// NOTE: CR: extra term switched off in massive implementation for the moment,
// mass of realEmission changed to mass of realEmitter
res *= ( 2./(1.-z+(1.-x)) - 2. -
sqr(realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass()) / prop * 2.*x);
res *= -ccme2;
res *=
pow(realEmissionME()->lastXComb().lastSHat() / underlyingBornME()->lastXComb().lastSHat(),
underlyingBornME()->lastXComb().mePartonData().size()-4.);
res *=
realEmissionME()->finalStateSymmetry() /
underlyingBornME()->finalStateSymmetry();
return res;
}
double FIMsqgxDipole::me2() 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());
// extra mass terms cancel
double res =
8.*Constants::pi*CF*(realEmissionME()->lastXComb().lastSHat())*
(underlyingBornME()->lastXComb().lastAlphaS())/prop;
// // NOTE: extra term taken from FIqgxDipole implementation
// res *= ( 2./(1.-z+(1.-x)) -2. +(1.-x)*(1.+3.*x*z) -
// sqr(realEmissionME()->lastXComb().mePartonData()[realEmission()]->hardProcessMass()) / prop * 2.*x);
// NOTE: CR: extra term switched off in massive implementation for the moment,
// mass of realEmission changed to mass of realEmitter
res *= ( 2./(1.-z+(1.-x)) - 2. -
sqr(realEmissionME()->lastXComb().mePartonData()[realEmitter()]->hardProcessMass()) / prop * 2.*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 FIMsqgxDipole::persistentOutput(PersistentOStream &) const {
}
void FIMsqgxDipole::persistentInput(PersistentIStream &, int) {
}
void FIMsqgxDipole::Init() {
static ClassDocumentation<FIMsqgxDipole> documentation
("FIMsqgxDipole");
DipoleRepository::registerDipole<0,FIMsqgxDipole,FIMassiveTildeKinematics,FIMassiveInvertedTildeKinematics>
("FIMsqgxDipole","FIMassiveTildeKinematics","FIMassiveInvertedTildeKinematics");
}
// *** 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<FIMsqgxDipole,SubtractionDipole>
describeHerwigFIMsqgxDipole("Herwig::FIMsqgxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.h b/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/FIMsqgxDipole.h
@@ -1,164 +1,156 @@
// -*- C++ -*-
//
// FIMsqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FIMsqgxDipole_H
#define HERWIG_FIMsqgxDipole_H
//
// This is the declaration of the FIMsqgxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Alexandra Wilcock, Christian Reuschle
*
* \brief FIMsqgxDipole implements the D_{sq,g}^a subtraction dipole.
*
*/
class FIMsqgxDipole: public SubtractionDipole {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIMsqgxDipole();
- /**
- * The destructor.
- */
- virtual ~FIMsqgxDipole();
- //@}
-
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(abs(partons[emitter]->id()) - 1000000) < 7 || abs(abs(partons[emitter]->id()) - 2000000) < 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;
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.
*/
FIMsqgxDipole & operator=(const FIMsqgxDipole &) = delete;
};
}
#endif /* HERWIG_FIMsqgxDipole_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,151 +1,149 @@
// -*- C++ -*-
//
// FIggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,166 +1,158 @@
// -*- C++ -*-
//
// FIggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#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,151 +1,149 @@
// -*- C++ -*-
//
// FIqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,160 +1,152 @@
// -*- C++ -*-
//
// FIqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#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,147 +1,145 @@
// -*- C++ -*-
//
// FIqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,168 +1,160 @@
// -*- C++ -*-
//
// FIqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#endif /* HERWIG_FIqqxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IFMggxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFMggxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IFMggxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IFMggxDipole.cc
@@ -1,152 +1,150 @@
// -*- C++ -*-
//
// IFMggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 "IFMggxDipole.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/IFMassiveTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h"
using namespace Herwig;
IFMggxDipole::IFMggxDipole()
: SubtractionDipole() {}
-IFMggxDipole::~IFMggxDipole() {}
-
IBPtr IFMggxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IFMggxDipole::fullclone() const {
return new_ptr(*this);
}
bool IFMggxDipole::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 IFMggxDipole::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 muj2 = sqr( (realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass()) ) /
(2.* (realEmissionME()->lastXComb().meMomenta()[bornSpectator()])*
(realEmissionME()->lastXComb().meMomenta()[realEmitter()]) );
double res = 1./(1.-x+u) + (1.-x)/x - 1. + x*(1.-x) -
muj2/x*u/(1.-u);
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;
}
double IFMggxDipole::me2() 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 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 IFMggxDipole::persistentOutput(PersistentOStream &) const {
}
void IFMggxDipole::persistentInput(PersistentIStream &, int) {
}
void IFMggxDipole::Init() {
static ClassDocumentation<IFMggxDipole> documentation
("IFMggxDipole");
DipoleRepository::registerDipole<0,IFMggxDipole,IFMassiveTildeKinematics,IFMassiveInvertedTildeKinematics>
("IFMggxDipole","IFMassiveTildeKinematics","IFMassiveInvertedTildeKinematics");
}
// *** 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<IFMggxDipole,SubtractionDipole>
describeHerwigIFMggxDipole("Herwig::IFMggxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IFMggxDipole.h b/MatrixElement/Matchbox/Dipoles/IFMggxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IFMggxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IFMggxDipole.h
@@ -1,160 +1,152 @@
// -*- C++ -*-
//
// IFMggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IFMggxDipole_H
#define HERWIG_IFMggxDipole_H
//
// This is the declaration of the IFMggxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IFMggxDipole implements the D^{g,g}_k subtraction dipole.
*
*/
class IFMggxDipole: public SubtractionDipole {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFMggxDipole();
- /**
- * The destructor.
- */
- virtual ~IFMggxDipole();
- //@}
-
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;
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.
*/
IFMggxDipole & operator=(const IFMggxDipole &) = delete;
};
}
#endif /* HERWIG_IFMggxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.cc
@@ -1,136 +1,134 @@
// -*- C++ -*-
//
// IFMgqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 "IFMgqxDipole.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/IFMassiveTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h"
using namespace Herwig;
IFMgqxDipole::IFMgqxDipole()
: SubtractionDipole() {}
-IFMgqxDipole::~IFMgqxDipole() {}
-
IBPtr IFMgqxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IFMgqxDipole::fullclone() const {
return new_ptr(*this);
}
bool IFMgqxDipole::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()) < 7 &&
partons[emission]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() != ZERO;
}
double IFMgqxDipole::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;
}
double IFMgqxDipole::me2() 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 *= -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 IFMgqxDipole::persistentOutput(PersistentOStream &) const {
}
void IFMgqxDipole::persistentInput(PersistentIStream &, int) {
}
void IFMgqxDipole::Init() {
static ClassDocumentation<IFMgqxDipole> documentation
("IFMgqxDipole");
DipoleRepository::registerDipole<0,IFMgqxDipole,IFMassiveTildeKinematics,IFMassiveInvertedTildeKinematics>
("IFMgqxDipole","IFMassiveTildeKinematics","IFMassiveInvertedTildeKinematics");
}
// *** 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<IFMgqxDipole,SubtractionDipole>
describeHerwigIFMgqxDipole("Herwig::IFMgqxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.h b/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IFMgqxDipole.h
@@ -1,160 +1,152 @@
// -*- C++ -*-
//
// IFMgqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IFMgqxDipole_H
#define HERWIG_IFMgqxDipole_H
//
// This is the declaration of the IFMgqxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IFMgqxDipole implements the D_k^{g,q} subtraction dipole.
*
*/
class IFMgqxDipole: public SubtractionDipole {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFMgqxDipole();
- /**
- * The destructor.
- */
- virtual ~IFMgqxDipole();
- //@}
-
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;
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.
*/
IFMgqxDipole & operator=(const IFMgqxDipole &) = delete;
};
}
#endif /* HERWIG_IFMgqxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.cc
@@ -1,154 +1,152 @@
// -*- C++ -*-
//
// IFMqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 "IFMqgxDipole.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/IFMassiveTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h"
using namespace Herwig;
IFMqgxDipole::IFMqgxDipole()
: SubtractionDipole() {}
-IFMqgxDipole::~IFMqgxDipole() {}
-
IBPtr IFMqgxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IFMqgxDipole::fullclone() const {
return new_ptr(*this);
}
bool IFMqgxDipole::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()) < 7 &&
partons[emitter]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() != ZERO;
}
double IFMqgxDipole::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;
// NOTE: extra term same as in IFqgxDipole
// NOTE: extra term switched off for the moment in the massive case
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;
}
double IFMqgxDipole::me2() 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;
// NOTE: extra term same as in IFqgxDipole
// NOTE: extra term switched off for the moment in the massive case
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 IFMqgxDipole::persistentOutput(PersistentOStream &) const {
}
void IFMqgxDipole::persistentInput(PersistentIStream &, int) {
}
void IFMqgxDipole::Init() {
static ClassDocumentation<IFMqgxDipole> documentation
("IFMqgxDipole");
// DipoleRepository::registerDipole<0,IFMqgxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics>
// ("IFMqgxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics");
DipoleRepository::registerDipole<0,IFMqgxDipole,IFMassiveTildeKinematics,IFMassiveInvertedTildeKinematics>
("IFMqgxDipole","IFMassiveTildeKinematics","IFMassiveInvertedTildeKinematics");
}
// *** 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<IFMqgxDipole,SubtractionDipole>
describeHerwigIFMqgxDipole("Herwig::IFMqgxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.h b/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IFMqgxDipole.h
@@ -1,160 +1,152 @@
// -*- C++ -*-
//
// IFMqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IFMqgxDipole_H
#define HERWIG_IFMqgxDipole_H
//
// This is the declaration of the IFMqgxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IFMqgxDipole implements the D^{q,g}_k subtraction dipole
*
*/
class IFMqgxDipole: public SubtractionDipole {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFMqgxDipole();
- /**
- * The destructor.
- */
- virtual ~IFMqgxDipole();
- //@}
-
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;
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.
*/
IFMqgxDipole & operator=(const IFMqgxDipole &) = delete;
};
}
#endif /* HERWIG_IFMqgxDipole_H */
diff --git a/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.cc b/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.cc
--- a/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.cc
+++ b/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.cc
@@ -1,167 +1,165 @@
// -*- C++ -*-
//
// IFMqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 "IFMqqxDipole.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"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h"
using namespace Herwig;
IFMqqxDipole::IFMqqxDipole()
: SubtractionDipole() {}
-IFMqqxDipole::~IFMqqxDipole() {}
-
IBPtr IFMqqxDipole::clone() const {
return new_ptr(*this);
}
IBPtr IFMqqxDipole::fullclone() const {
return new_ptr(*this);
}
bool IFMqqxDipole::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 &&
abs(partons[emission]->id()) < 7 &&
abs(partons[emitter]->id()) < 7 &&
partons[emission]->id() - partons[emitter]->id() == 0 &&
// !(partons[emitter]->hardProcessMass() == ZERO &&
// partons[emission]->hardProcessMass() == ZERO &&
// partons[spectator]->hardProcessMass() == ZERO);
partons[emitter]->hardProcessMass() == ZERO &&
partons[emission]->hardProcessMass() == ZERO &&
partons[spectator]->hardProcessMass() != ZERO;
}
double IFMqqxDipole::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 muj2 = sqr( (realEmissionME()->lastXComb().mePartonData()[realSpectator()]->hardProcessMass()) ) /
(2.* (realEmissionME()->lastXComb().meMomenta()[bornSpectator()])*
(realEmissionME()->lastXComb().meMomenta()[realEmitter()]) );
double res = x + 2.*(1.-x)/x -
2.*muj2/x*u/(1.-u);
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;
}
double IFMqqxDipole::me2() 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;
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 IFMqqxDipole::persistentOutput(PersistentOStream &) const {
}
void IFMqqxDipole::persistentInput(PersistentIStream &, int) {
}
void IFMqqxDipole::Init() {
static ClassDocumentation<IFMqqxDipole> documentation
("IFMqqxDipole");
// DipoleRepository::registerDipole<0,IFMqqxDipole,IFLightTildeKinematics,IFLightInvertedTildeKinematics>
// ("IFMqqxDipole","IFLightTildeKinematics","IFLightInvertedTildeKinematics");
DipoleRepository::registerDipole<0,IFMqqxDipole,IFMassiveTildeKinematics,IFMassiveInvertedTildeKinematics>
("IFMqqxDipole","IFMassiveTildeKinematics","IFMassiveInvertedTildeKinematics");
}
// *** 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<IFMqqxDipole,SubtractionDipole>
describeHerwigIFMqqxDipole("Herwig::IFMqqxDipole", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.h b/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.h
--- a/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.h
+++ b/MatrixElement/Matchbox/Dipoles/IFMqqxDipole.h
@@ -1,162 +1,154 @@
// -*- C++ -*-
//
// IFMqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IFMqqxDipole_H
#define HERWIG_IFMqqxDipole_H
//
// This is the declaration of the IFMqqxDipole class.
//
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IFMqqxDipole implements the D^{q,qbar}_k subtraction dipole.
*
*/
class IFMqqxDipole: public SubtractionDipole {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFMqqxDipole();
- /**
- * The destructor.
- */
- virtual ~IFMqqxDipole();
- //@}
-
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;
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.
*/
IFMqqxDipole & operator=(const IFMqqxDipole &) = delete;
};
}
#endif /* HERWIG_IFMqqxDipole_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,150 +1,148 @@
// -*- C++ -*-
//
// IFggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,160 +1,152 @@
// -*- C++ -*-
//
// IFggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#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,140 +1,138 @@
// -*- C++ -*-
//
// IFgqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,160 +1,152 @@
// -*- C++ -*-
//
// IFgqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#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,151 +1,149 @@
// -*- C++ -*-
//
// IFqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,160 +1,152 @@
// -*- C++ -*-
//
// IFqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#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,155 +1,153 @@
// -*- C++ -*-
//
// IFqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,162 +1,154 @@
// -*- C++ -*-
//
// IFqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#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,149 +1,147 @@
// -*- C++ -*-
//
// IIggxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,159 +1,151 @@
// -*- C++ -*-
//
// IIggxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#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,140 +1,138 @@
// -*- C++ -*-
//
// IIgqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,160 +1,152 @@
// -*- C++ -*-
//
// IIgqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#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,144 +1,142 @@
// -*- C++ -*-
//
// IIqgxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,160 +1,152 @@
// -*- C++ -*-
//
// IIqgxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#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,155 +1,153 @@
// -*- C++ -*-
//
// IIqqxDipole.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
}
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,162 +1,154 @@
// -*- C++ -*-
//
// IIqqxDipole.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
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 &) = delete;
};
}
#endif /* HERWIG_IIqqxDipole_H */
diff --git a/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.cc b/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.cc
--- a/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.cc
+++ b/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.cc
@@ -1,1069 +1,1067 @@
// -*- C++ -*-
//
// GoSamAmplitude.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the GoSamAmplitude class.
//
#include "GoSamAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Utilities/StringUtils.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
#include "Herwig/API/Filesystem.h"
#include <fstream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <exception>
namespace bfs = Herwig::filesystem;
using namespace Herwig;
#ifndef HERWIG_BINDIR
#error Makefile.am needs to define HERWIG_BINDIR
#endif
#ifndef HERWIG_PKGDATADIR
#error Makefile.am needs to define HERWIG_PKGDATADIR
#endif
#ifndef GOSAM_PREFIX
#error Makefile.am needs to define GOSAM_PREFIX
#endif
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
GoSamAmplitude::GoSamAmplitude() :
theAccuracyTarget(6),theCodeExists(false),theFormOpt(true),theNinja(true),
theHiggsEff(false),theMassiveLeptons(false),theLoopInducedOption(0),
isitDR(false),doneGoSamInit(false),doneGoSamInitRun(false),
bindir_(HERWIG_BINDIR), pkgdatadir_(HERWIG_PKGDATADIR), GoSamPrefix_(GOSAM_PREFIX)
{}
-GoSamAmplitude::~GoSamAmplitude() {}
-
IBPtr GoSamAmplitude::clone() const {
return new_ptr(*this);
}
IBPtr GoSamAmplitude::fullclone() const {
return new_ptr(*this);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void GoSamAmplitude::doinit() {
optionalContractFile() = name() + ".OLPContract.lh";
MatchboxOLPME::doinit();
doneGoSamInit = true;
}
void GoSamAmplitude::doinitrun() {
optionalContractFile() = name() + ".OLPContract.lh";
MatchboxOLPME::doinitrun();
doneGoSamInitRun = true;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
extern "C" void OLP_Start(const char*, int* i);
extern "C" void OLP_Polvec(double*, double*, double*);
extern "C" void OLP_SetParameter(char*, double*, double*, int*);
extern "C" void OLP_PrintParameter(char*);
extern "C" void OLP_EvalSubProcess2(int*, double*, double*, double*, double*);
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool GoSamAmplitude::startOLP(const map<pair<Process, int>, int>& procs) {
char char_cwd[256];
getcwd(char_cwd, sizeof(char_cwd));
string cwd = string(char_cwd);
string folderMatchboxBuild = factory()->buildStorage();
folderMatchboxBuild.erase(folderMatchboxBuild.begin());
// set all necessary path and file names
gosamPath = gosamPathInterface == "" ? cwd + folderMatchboxBuild + "GoSam" : gosamPathInterface;
// When transitioning to C++ 11 this length()-1 workaround can be replaced by string.back()
if (gosamPath.at(gosamPath.length()-1) != '/') gosamPath.append("/");
gosamSourcePath = gosamPath + "source/";
gosamInstallPath = gosamPath + "build/";
// create all the directories
if (!bfs::is_directory(gosamPath)){
try {
bfs::create_directory(gosamPath);
} catch (exception& e) {
throw Exception()
<< "--------------------------------------------------------------------------------\n"
<< "The following exception occured:\n\n"
<< " " << e.what() << "\n\n"
<< " -> Please create the parent directory of\n"
<< " " << gosamPath << "\n"
<< " manually!\n"
<< "--------------------------------------------------------------------------------\n"
<< Exception::runerror;
}
}
if (!bfs::is_directory(gosamSourcePath)) bfs::create_directory(gosamSourcePath);
if (!bfs::is_directory(gosamInstallPath)) bfs::create_directory(gosamInstallPath);
contractFileTitle = name() + ".OLPContract.lh";
contractFileName = gosamPath + "/" + contractFileTitle;
string orderFileName = gosamPath + "/" + name() + ".OLPOrder.lh";
// Set the path variable (plus file name) where to find the GoSam specific input file
gosamSetupInFileName = gosamSetupInFileNameInterface == "" ? gosamPath + "/setup.gosam.in" : gosamSetupInFileNameInterface;
// Use the python script gosam2herwig to make replacements in the GoSam
// specific input file at gosamSetupInFileName. If the GoSam input file
// does not exist yet at gosamSetupInFileName the python script will get
// it from src/defaults/ before making the replacements.
string cmd = "python "+bindir_+"/gosam2herwig ";
cmd+=" --usrinfile="+gosamSetupInFileNameInterface;
cmd+=" --infile="+gosamSetupInFileName+".tbu";
cmd+=" --definfile="+pkgdatadir_+"/defaults/setup.gosam.in";
cmd+=" --formtempdir="+StringUtils::replace(gosamSourcePath, string("/"), string("\\/")); //@FORMTEMPDIR@
cmd+=" --reduction="+(theNinja ? string("ninja,golem95") : string("samurai,golem95")); //@REDUCTIONPROGRAMS@
cmd+=" --formopt="+(theFormOpt ? string("") : string(", noformopt")); //@FORMOPT@
cmd+=" --higgseff="+(theHiggsEff ? string("smehc") : string("smdiag")); //@MODEL@
std::system(cmd.c_str());
if ( factory()->initVerbose() ) {
generator()->log() << "\n\n>>> NOTE: According to the repository settings for the GoSam interface:\n" << flush;
if (theHiggsEff) generator()->log() << "\n -- GoSam will use a model with an effective ggH coupling (model=smehc).\n" << flush;
else if (!theHiggsEff) generator()->log() << "\n -- GoSam will use its default model (model=smdiag).\n" << flush;
if (theNinja) generator()->log() << " -- GoSam will use Ninja as reduction program (reduction_programs=ninja,golem95).\n" << flush;
else if (!theNinja) generator()->log() << " -- GoSam will use Samurai as reduction program (reduction_programs=samurai,golem95).\n" << flush;
if (theFormOpt) generator()->log() << " -- Form optimization switched on (extensions=autotools).\n" << flush;
else if (!theFormOpt) generator()->log() << " -- Form optimization switched off (extensions=autotools, noformopt).\n" << flush;
if (theNinja && !theFormOpt) throw Exception() << "GoSamAmplitude: Ninja reduction needs form optimization!\n" << Exception::runerror;
if (gosamSetupInFileNameInterface == "") {
generator()->log() << "\n Please be aware that you are using a copy of the default GoSam input file!\n"
<< " Please note that if you need special options to be considered for the specific\n"
<< " process you are looking at (diagram filtering, etc.) these are not automatically\n"
<< " set for you. In that case please consider to specify your own GoSam input file\n"
<< " via 'set " << name() << ":SetupInFilename' in the input file.\n\n" << flush;
}
// If one uses a custom GoSam input file at gosamSetupInFileName = gosamSetupInFileNameInterface
// then please note that not all options in there might match the corresponding Herwig repository
// options
if (gosamSetupInFileNameInterface != "") {
generator()->log() << "\n Please be aware that you are using a custom GoSam input file!\n"
<< " Please note that if you have set the options for model, reduction_programs,\n"
<< " extensions and/or form.tempdir manually these will of course not be replaced\n"
<< " by the corresponding repository settings mentioned above.\n\n" << flush;
}
generator()->log() << "\n>>> NOTE: GoSam may return the set of used parameters for this process via the OLP_PrintParameter() function:\n\n"
<< " -- If Debug::level > 1, the OLP parameters are being written to file: at " << factory()->runStorage() + name() + ".OLPParameters.lh.\n\n" << flush;
}
double accuracyTarget = 1.0/pow(10.0,accuracyTargetNegExp());
time_t rawtime;
time (&rawtime);
accuracyFileTitle = name() + ".OLPAccuracy.lh";
accuracyFile = factory()->buildStorage() + accuracyFileTitle;
ofstream accuracyFileStream;
if ( Debug::level > 1 ) {
accuracyFileStream.open(accuracyFile.c_str()); // Opening accuracyFile once here removes all previous content before the read step
accuracyFileStream << "\nFile to contain those PSPs for which GoSam evaluated one-loop interference terms or loop induced ME2s\n"
<< "with acc > target accuracy = " << accuracyTarget << ". Date/Time: " << ctime(&rawtime) << endl;
}
if ( factory()->initVerbose() ) {
generator()->log() << "\n>>> NOTE: GoSam will return the accuracy of one-loop interference terms or loop induced ME2s\n"
<< " at every PSP via the BLHA2 acc parameter:\n\n"
<< " -- In cases where acc > 10^-AccuracyTarget = " << accuracyTarget << " the corresponding PSPs are being dis-\n"
<< " carded.\n"
<< " -- The default value for AccuracyTarget is 6, but you may consider setting it otherwise\n"
<< " via 'set " << name() << ":AccuracyTarget' in the input file.\n"
<< " -- Currently the value for AccuracyTarget is set to " << accuracyTargetNegExp() << ".\n"
<< " -- If Debug::level > 1, the discarded PSPs are being written to file: at " + accuracyFile << ".\n"
<< " -- If the amount of PSPs with acc > " << accuracyTarget << " is significant, please consider to re-evaluate\n"
<< " your process setup (accuracy target, masses, cuts, etc.)!\n\n\n" << flush;
}
// check for old order file and create it if it doesn't already exist
fillOrderFile(procs, orderFileName);
ifstream ifile(contractFileName.c_str());
if(!ifile){
signOLP(orderFileName, contractFileName);
}
if ( !checkOLPContract(contractFileName) ) {
throw Exception() << "GoSamAmplitude: failed to start GoSam" << Exception::runerror;
}
if (!( DynamicLoader::load(gosamInstallPath+"/lib/libgolem_olp.so")
|| DynamicLoader::load(gosamInstallPath+"/lib64/libgolem_olp.so")
|| DynamicLoader::load(gosamInstallPath+"/lib/libgolem_olp.dylib")
|| DynamicLoader::load(gosamInstallPath+"/lib64/libgolem_olp.dylib"))) buildGoSam();
int status = -1;
startOLP(contractFileTitle, status);
if ( status != 1 ) return false;
return true;
}
void GoSamAmplitude::startOLP(const string& contract, int& status) {
string tempcontract = contract;
char char_cwd[256];
getcwd(char_cwd, sizeof(char_cwd));
string cwd = string(char_cwd);
string folderMatchboxBuild = factory()->buildStorage();
folderMatchboxBuild.erase(folderMatchboxBuild.begin());
gosamPath = gosamPathInterface == "" ? cwd + folderMatchboxBuild + "GoSam" : gosamPathInterface;
// When transitioning to C++ 11 this length()-1 workaround can be replaced by string.back()
if (gosamPath.at(gosamPath.length()-1) != '/') gosamPath.append("/");
if (!( DynamicLoader::load(gosamPath+"build/lib/libgolem_olp.so")
|| DynamicLoader::load(gosamPath+"build/lib64/libgolem_olp.so")
|| DynamicLoader::load(gosamPath+"build/lib/libgolem_olp.dylib")
|| DynamicLoader::load(gosamPath+"build/lib64/libgolem_olp.dylib")))
throw Exception() << "GoSamAmplitude: Failed to load GoSam. Please check the log file.\n"
<< Exception::runerror;
tempcontract = gosamPath + tempcontract;
OLP_Start(tempcontract.c_str(), &status);
// hand over input parameters for EW scheme considered
int pStatus = 0;
double zero = 0.0;
if ( SM().ewScheme() == 0 || SM().ewScheme() == 6 ) { // EW/Scheme Default and EW/Scheme Independent
throw Exception() << "GoSamAmplitude: `Best value' schemes are not supported by GoSam"
<< Exception::runerror;
} else if ( SM().ewScheme() == 4 ) { // EW/Scheme mW (uses mW,GF,sin2thetaW) seems not to be supported by GoSam
throw Exception() << "GoSamAmplitude: `mW' scheme is not supported by GoSam"
<< Exception::runerror;
} else if ( SM().ewScheme() == 1 ) { // EW/Scheme GMuScheme (uses mW,mZ,GF)
double in1=getParticleData(ParticleID::Z0)->hardProcessMass()/GeV;
double in2=getParticleData(ParticleID::Wplus)->hardProcessMass()/GeV;
double in3=SM().fermiConstant()*GeV2;
OLP_SetParameter((char *)"mass(23)",&in1,&zero,&pStatus);
OLP_SetParameter((char *)"mass(24)",&in2,&zero,&pStatus);
OLP_SetParameter((char *)"Gf",&in3,&zero,&pStatus);
} else if ( SM().ewScheme() == 2 ) { // EW/Scheme alphaMZScheme (uses mW,mZ,alpha(mZ))
double in1=getParticleData(ParticleID::Z0)->hardProcessMass()/GeV;
double in2=getParticleData(ParticleID::Wplus)->hardProcessMass()/GeV;
double in3=SM().alphaEMMZ();
OLP_SetParameter((char *)"mass(23)",&in1,&zero,&pStatus);
OLP_SetParameter((char *)"mass(24)",&in2,&zero,&pStatus);
OLP_SetParameter((char *)"alpha",&in3,&zero,&pStatus);
} else if ( SM().ewScheme() == 3 ) { // EW/Scheme NoMass (uses alpha(mZ),GF,sin2thetaW)
double in1=SM().fermiConstant()*GeV2;
double in2=SM().alphaEMMZ();
double in3=SM().sin2ThetaW();
OLP_SetParameter((char *)"Gf",&in1,&zero,&pStatus);
OLP_SetParameter((char *)"alpha",&in2,&zero,&pStatus);
OLP_SetParameter((char *)"sw2",&in3,&zero,&pStatus);
} else if ( SM().ewScheme() == 5 ) { // EW/Scheme mZ (uses mZ,alphaEM,sin2thetaW)
double in1=getParticleData(ParticleID::Z0)->hardProcessMass()/GeV;
double in2=SM().alphaEMMZ();
double in3=SM().sin2ThetaW();
OLP_SetParameter((char *)"mass(23)",&in1,&zero,&pStatus);
OLP_SetParameter((char *)"alpha",&in2,&zero,&pStatus);
OLP_SetParameter((char *)"sw2",&in3,&zero,&pStatus);
} else if ( SM().ewScheme() == 7 ) { // EW/Scheme FeynRulesUFO (uses mZ,GF,alpha(mZ))
double in1=getParticleData(ParticleID::Z0)->hardProcessMass()/GeV;
double in2=SM().alphaEMMZ();
double in3=SM().fermiConstant()*GeV2;
OLP_SetParameter((char *)"mass(23)",&in1,&zero,&pStatus);
OLP_SetParameter((char *)"alpha",&in2,&zero,&pStatus);
OLP_SetParameter((char *)"Gf",&in3,&zero,&pStatus);
}
// hand over widths of Z and W
double wZ = getParticleData(23)->hardProcessWidth()/GeV;
double wW = getParticleData(24)->hardProcessWidth()/GeV;
OLP_SetParameter((char*)"width(23)",&wZ,&zero,&pStatus);
OLP_SetParameter((char*)"width(24)",&wW,&zero,&pStatus);
// hand over mass and width of the Higgs
double wH = getParticleData(25)->hardProcessWidth()/GeV;
double mH = getParticleData(25)->hardProcessMass()/GeV;
OLP_SetParameter((char*)"width(25)",&wH,&zero,&pStatus);
OLP_SetParameter((char*)"mass(25)",&mH,&zero,&pStatus);
// hand over initial input parameter for alphaS
double as = SM().alphaS();
OLP_SetParameter((char *)"alphaS", &as, &zero, &pStatus);
// fill massive Particle vector
if (massiveParticles.empty()) {
// with quark masses
for (int i=1; i<=6; ++i)
if (getParticleData(i)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(i);
// with lepton masses
- if (theMassiveLeptons && getParticleData(11)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(11);
- if (theMassiveLeptons && getParticleData(13)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(13);
- if (theMassiveLeptons && getParticleData(15)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(15);
+ if (theMassiveLeptons && getParticleData(11)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(11);
+ if (theMassiveLeptons && getParticleData(13)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(13);
+ if (theMassiveLeptons && getParticleData(15)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(15);
}
// hand over quark (and possibly lepton) masses and widths (iff massive)
if ( massiveParticles.size() != 0 ) {
for ( vector<int>::const_iterator mID = massiveParticles.begin(); mID != massiveParticles.end(); ++mID ) {
string mstr;
string wstr;
int mInt = *mID;
double mass=getParticleData(mInt)->hardProcessMass()/GeV;
double width=getParticleData(mInt)->hardProcessWidth()/GeV;
std::stringstream ss;
ss << mInt;
string str = ss.str();
mstr="mass("+str+")";
wstr="width("+str+")";
char * mchar = new char[mstr.size()+1];
char * wchar = new char[wstr.size()+1];
std::copy(mstr.begin(),mstr.end(),mchar);
std::copy(wstr.begin(),wstr.end(),wchar);
mchar[mstr.size()] = '\0';
wchar[wstr.size()] = '\0';
OLP_SetParameter( mchar, &mass, &zero, &pStatus );
OLP_SetParameter( wchar, &width, &zero, &pStatus );
delete[] mchar;
delete[] wchar;
// Nicer but not working properly:
// double mass=getParticleData(*mID)->hardProcessMass()/GeV;
// double width=getParticleData(*mID)->hardProcessWidth()/GeV;
// string mstr="mass("+static_cast<ostringstream*>(&(ostringstream()<<(*mID)))->str()+")";
// string wstr="width("+static_cast<ostringstream*>(&(ostringstream()<<(*mID)))->str()+")";
// cout<<"\n massiv "<<mstr;
//
// OLP_SetParameter((char *)&mstr,&mass, &zero, &pStatus );
// OLP_SetParameter((char *)&wstr,&width, &zero, &pStatus );
}
}
// Note: In the GoSam input file, the standard is to set the parameter
// 'symmetries' for quark families and lepton generations, which allow
// for flavour changing only between families/generations. If this pa-
// rameter is set, GoSam won't allow to set electron and muon mass and
// width via the interface. Also setting mass and width for the tau is
// not yet considered.
// print OLP parameters
if ( Debug::level > 1 ) {
string ppstr = factory()->runStorage() + name() + ".OLPParameters.lh";
OLP_PrintParameter(const_cast<char*>(ppstr.c_str()));
}
didStartOLP() = true;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void GoSamAmplitude::fillOrderFile(const map<pair<Process, int>, int>& procs, string orderFileName) {
for ( map<pair<Process, int>, int>::const_iterator p = procs.begin() ; p != procs.end() ; ++p ) {
std::stringstream Processstr;
std::stringstream Typestr;
Processstr << (*p).first.first.legs[0]->id() << " " << (*p).first.first.legs[1]->id() << " -> ";
for ( PDVector::const_iterator o = (*p).first.first.legs.begin() + 2 ; o != (*p).first.first.legs.end() ; ++o )
Processstr << (**o).id() << " ";
if ( (*p).first.second == ProcessType::treeME2 ) {
Typestr << "Tree";
} else if ( (*p).first.second == ProcessType::loopInducedME2 ) {
Typestr << "LoopInduced";
} else if ( (*p).first.second == ProcessType::colourCorrelatedME2 ) {
Typestr << "ccTree";
} else if ( (*p).first.second == ProcessType::spinColourCorrelatedME2 ) {
Typestr << "scTree";
} else if ( (*p).first.second == ProcessType::oneLoopInterference ) {
Typestr << "Loop";
}
gosamprocinfo pro = gosamprocinfo((*p).second, -1, Processstr.str(), Typestr.str());
pro.setOAs(p->first.first.orderInAlphaS);
pro.setOAew(p->first.first.orderInAlphaEW);
processmap[(*p).second] = pro;
}
ifstream oldOrderFileStream(orderFileName.c_str());
if (oldOrderFileStream){
oldOrderFileStream.close();
return;
}
ofstream orderFile(orderFileName.c_str());
int asPower = 100;
int minlegs = 100;
int maxlegs = -1;
int maxasPower = -1;
int aewPower = 100;
int maxaewPower = -1;
for ( map<pair<Process, int>, int>::const_iterator t = procs.begin() ; t != procs.end() ; ++t ) {
asPower = min(asPower, static_cast<int>(t->first.first.orderInAlphaS));
minlegs = min(minlegs, static_cast<int>(t->first.first.legs.size()));
maxlegs = max(maxlegs, static_cast<int>(t->first.first.legs.size()));
maxasPower = max(maxasPower, static_cast<int>(t->first.first.orderInAlphaS));
aewPower = min(aewPower, static_cast<int>(t->first.first.orderInAlphaEW));
maxaewPower = max(maxaewPower, static_cast<int>(t->first.first.orderInAlphaEW));
}
orderFile << "# OLP order file created by Herwig/Matchbox for GoSam\n\n";
orderFile << "InterfaceVersion BLHA2\n";
orderFile << "MatrixElementSquareType CHsummed\n";
orderFile << "CorrectionType QCD\n";
orderFile << "IRregularisation " << (isDR() ? "DRED" : "CDR") << "\n";
// loop over quarks to check if they have non-zero masses
for (int i=1; i<=6; ++i) if (getParticleData(i)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(i);
// check if leptons have non-zero masses (iff theMassiveLeptons==true)
if (theMassiveLeptons && getParticleData(11)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(11);
if (theMassiveLeptons && getParticleData(13)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(13);
if (theMassiveLeptons && getParticleData(15)->hardProcessMass()/GeV > 0.0) massiveParticles.push_back(15);
if ( massiveParticles.size() != 0 ) {
orderFile << "MassiveParticles ";
for ( vector<int>::const_iterator mID = massiveParticles.begin(); mID != massiveParticles.end(); ++mID ) {
int mInt = *mID;
orderFile << mInt << " ";
}
orderFile << "\n";
}
orderFile << "\n";
vector < string > types;
types.push_back("Tree");
types.push_back("LoopInduced");
types.push_back("ccTree");
types.push_back("scTree");
types.push_back("Loop");
for ( int i = asPower ; i != maxasPower + 1 ; i++ ) {
for ( int j = aewPower ; j != maxaewPower + 1 ; j++ ) {
orderFile << "\nAlphasPower " << i << "\n";
orderFile << "AlphaPower " << j << "\n";
for ( vector<string>::iterator it = types.begin() ; it != types.end() ; it++ ) {
if ( *it == "LoopInduced" ) continue;
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; ++p )
if ( (*p).second.Tstr() == *it && i == (*p).second.orderAs() && j == (*p).second.orderAew() ) {
orderFile << "\nAmplitudeType " << *it << "\n";
break;
}
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; ++p )
if ( (*p).second.Tstr() == *it && i == (*p).second.orderAs() && j == (*p).second.orderAew() ) {
orderFile << (*p).second.Pstr() << "\n";
}
}
}
}
// Write out the loop induced processes separately
int asPowerLI = 100;
int aewPowerLI = 100;
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; ++p ) {
if ( (*p).second.Tstr() != "LoopInduced" ) continue;
if ( (*p).second.orderAs() != asPowerLI || (*p).second.orderAew() != aewPowerLI ) {
asPowerLI = (*p).second.orderAs();
aewPowerLI = (*p).second.orderAew();
// At the moment GoSam requires for qcd loop induced processes the as coupling power
// which would correspond to an associated fictitious Born process
orderFile << "\nAlphasPower " << (asPowerLI-2) << "\n";
orderFile << "AlphaPower " << aewPowerLI << "\n";
orderFile << "\nAmplitudeType " << "LoopInduced" << "\n";
}
orderFile << (*p).second.Pstr() << "\n";
}
orderFile << flush;
}
void GoSamAmplitude::signOLP(const string& order, const string& contract) {
if(!theCodeExists){
char char_cwd[256];
getcwd(char_cwd, sizeof(char_cwd));
string cwd = string(char_cwd);
string folderMatchboxBuild = factory()->buildStorage();
folderMatchboxBuild.erase(folderMatchboxBuild.begin());
generator()->log() << "\n>>> generating GoSam amplitudes. This may take some time, please be patient.\n"
<< ">>> see " + cwd + folderMatchboxBuild + "gosam-amplitudes.log for details.\n" << flush;
string cmd = GoSamPrefix_+"/bin/gosam.py --olp --output-file=" + contract + " --config=" +
gosamSetupInFileName+".tbu" + " --destination=" + gosamSourcePath + " " + order + " > " + cwd + folderMatchboxBuild + "gosam-amplitudes.log 2>&1";
std::system(cmd.c_str());
cmd = "python "+bindir_+"/gosam2herwig ";
cmd += " --makelink ";
// cmd += " --makelinkfrom=contract ";
cmd += " --makelinkfrom="+gosamPath+"/"+name()+".OLPContract.lh";
cmd += " --makelinkto="+factory()->buildStorage() + name() + ".OLPContract.lh";
std::system(cmd.c_str());
}
}
bool GoSamAmplitude::checkOLPContract(string contractFileName) {
ifstream infile(contractFileName.c_str());
string line;
vector < string > contractfile;
while (std::getline(infile, line)) contractfile.push_back(line);
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; p++ ) {
bool righttype = false;
for ( vector<string>::iterator linex = contractfile.begin() ; linex != contractfile.end() ; ++linex ) {
if ( (*linex).find("AmplitudeType ")!= std::string::npos ) {
if ( (*linex).find(" " + (*p).second.Tstr() + " ")!= std::string::npos ) {
righttype = true;
} else {
righttype = false;
}
}
if ( righttype ) {
if ( (*linex).find((*p).second.Pstr()) != std::string::npos && (*p).second.Pstr().length() == (*linex).find("|") ) {
string sub = (*linex).substr((*linex).find("|") + 1, (*linex).find("#") - (*linex).find("|") - 1); // | 1 23 # buggy??
if ( sub.find(" 1 ") != 0 )
throw Exception() << "GoSamAmplitude: Failed to check contractfile. Please check the logfile.\n"
<< Exception::runerror;
string subx = sub.substr(3);
int subint;
istringstream(subx) >> subint;
(*p).second.setGID(subint);
}
}
}
}
string ids = factory()->buildStorage() + "GoSam.ids.dat";
ofstream IDS(ids.c_str());
idpair.clear();
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; p++ )
idpair.push_back(-1);
idpair.push_back(-1);
for ( map<int, gosamprocinfo>::iterator p = processmap.begin() ; p != processmap.end() ; p++ ) {
idpair[(*p).second.HID()]=(*p).second.GID();
IDS << (*p).second.HID() << " " << (*p).second.GID() << " " << (*p).second.Tstr() << "\n";
if ( (*p).second.GID() == -1 ) return 0;
}
IDS << flush;
return 1;
}
bool GoSamAmplitude::buildGoSam() {
if(!theCodeExists){
generator()->log() << "\n>>> compiling GoSam amplitudes. This may take some time, please be patient.\n"
<< ">>> see " + gosamSourcePath + "gosam-build.log for details.\n\n" << flush;
string cmd = "cd " + gosamSourcePath + " && sh autogen.sh FCFLAGS=-g --prefix=" +
gosamInstallPath + " --disable-static > gosam-build.log 2>&1";
std::system(cmd.c_str());
if (!gosamBuildScript.empty()) {
cmd = "cd " + gosamSourcePath + " && " + gosamBuildScript + " >> gosam-build.log 2>&1";
std::system(cmd.c_str());
}
std::system(cmd.c_str());
cmd = "cd " + gosamSourcePath + " && make install >> gosam-build.log 2>&1";
std::system(cmd.c_str());
}
theCodeExists=true;
return 1;
}
void GoSamAmplitude::getids() const {
string line = factory()->buildStorage() + "GoSam.ids.dat";
ifstream infile(line.c_str());
int hid;
int gid;
string type;
while (std::getline(infile, line)) {
idpair.push_back(-1);
idtypepair.push_back(" ");
}
infile.close();
string line2 = factory()->buildStorage() + "GoSam.ids.dat";
ifstream infile2(line2.c_str());
idpair.push_back(-1);
idtypepair.push_back(" ");
while (std::getline(infile2, line2)) {
istringstream(line2) >> hid >> gid >> type;
idpair[hid]=gid;
idtypepair[hid]=type;
}
infile.close();
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void GoSamAmplitude::evalSubProcess() const {
useMe();
double units = pow(lastSHat() / GeV2, int(mePartonData().size()) - 4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double scale = sqrt(mu2() / GeV2);
if (hasRunningAlphaS()) {
int pStatus = 0;
double zero = 0.0;
double as;
as = lastAlphaS();
OLP_SetParameter((char *)"alphaS", &as, &zero, &pStatus);
}
double out[7] = { };
double acc;
if ( idpair.size() == 0 ){ getids(); }
int id = -99;
if ( olpId()[ProcessType::loopInducedME2] ) id = olpId()[ProcessType::loopInducedME2];
else if ( olpId()[ProcessType::oneLoopInterference] ) id = olpId()[ProcessType::oneLoopInterference];
else id = olpId()[ProcessType::treeME2];
int callid(idpair[id]); // If id denotes the Herwig ID, this returns the GoSam ID
string calltype(idtypepair[id]); // If id denotes the Herwig ID, this returns the amplitude type
OLP_EvalSubProcess2(&(callid), olpMomenta(), &scale, out, &acc);
double accuracyTarget = 1.0/pow(10.0,accuracyTargetNegExp());
accuracyFileTitle = name() + ".OLPAccuracy.lh";
accuracyFile = factory()->buildStorage() + accuracyFileTitle;
ofstream accuracyFileStream;
if ( (olpId()[ProcessType::oneLoopInterference]||olpId()[ProcessType::loopInducedME2]) && acc > accuracyTarget ) {
if ( Debug::level > 1 ) {
accuracyFileStream.open(accuracyFile.c_str(),ios::app);
vector<Lorentz5Momentum> currentpsp = lastXComb().meMomenta();
time_t rawtime;
time (&rawtime);
if (doneGoSamInit) accuracyFileStream << "READ phase: ";
else if (doneGoSamInitRun) accuracyFileStream << "RUN phase: ";
accuracyFileStream << "Sub-process with Herwig ID = " << id << " and GoSam ID = " << callid << ", " << ctime(&rawtime);
accuracyFileStream << "GoSam evaluated one-loop interference or loop induced ME2 with acc = " << acc
<< " > target accuracy = " << accuracyTarget << ", at PSP [in units of GeV]:" << endl;
for (size_t i=0; i!=currentpsp.size(); ++i) {
accuracyFileStream << "(t,x,y,z,mass;m)[" << i << "]=("
<< currentpsp[i].t()/GeV << ","
<< currentpsp[i].x()/GeV << ","
<< currentpsp[i].y()/GeV << ","
<< currentpsp[i].z()/GeV << ","
<< currentpsp[i].mass()/GeV << ";"
<< currentpsp[i].m()/GeV << ")"
<< endl;
}
accuracyFileStream << endl;
}
throw Veto(); // Dispose of PSP
}
if ( olpId()[ProcessType::oneLoopInterference] ) {
if (calculateTreeME2()) lastTreeME2(out[3] * units);
lastOneLoopInterference((out[2])* units);
lastOneLoopPoles(pair<double, double>(out[0] * units, out[1] * units));
} else if ( olpId()[ProcessType::treeME2] ) {
lastTreeME2(out[3] * units);
} else if ( olpId()[ProcessType::loopInducedME2] ) {
lastTreeME2(out[2] * units);
}
}
void GoSamAmplitude::evalColourCorrelator(pair<int, int> ) const {
double units = pow(lastSHat() / GeV2, int(mePartonData().size()) - 4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double scale = sqrt(mu2() / GeV2);
if (hasRunningAlphaS()) {
int pStatus = 0;
double zero = 0.0;
double as;
as = lastAlphaS();
OLP_SetParameter((char *)"alphaS", &as, &zero, &pStatus);
}
int n = lastXComb().meMomenta().size();
colourCorrelatorResults.resize(n * (n - 1) / 2);
if ( idpair.size() == 0 ) getids();
int callid(idpair[olpId()[ProcessType::colourCorrelatedME2]]);
double acc;
OLP_EvalSubProcess2(&(callid), olpMomenta(), &scale, &colourCorrelatorResults[0], &acc);
cPDVector particles = lastXComb().matrixElement()->mePartonData();
for ( int i = 0 ; i < n ; ++i ) {
for ( int j = i + 1 ; j < n ; ++j ) {
lastColourCorrelator(make_pair(i, j), colourCorrelatorResults[i+j*(j-1)/2] * units);
}
}
}
void GoSamAmplitude::evalSpinColourCorrelator(pair<int , int > ) const {
double units = pow(lastSHat() / GeV2, int(mePartonData().size()) - 4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double scale = sqrt(mu2() / GeV2);
if (hasRunningAlphaS()) {
int pStatus = 0;
double zero = 0.0;
double as;
as = lastAlphaS();
OLP_SetParameter((char *)"alphaS", &as, &zero, &pStatus);
}
int n = lastXComb().meMomenta().size();
spinColourCorrelatorResults.resize(2*n*n);
if ( idpair.size() == 0 ) getids();
double acc;
int callid(idpair[olpId()[ProcessType::spinColourCorrelatedME2]]);
OLP_EvalSubProcess2(&(callid), olpMomenta(), &scale, &spinColourCorrelatorResults[0], &acc);
for ( int i = 0; i < n; ++i ) {
for ( int j = 0; j < n; ++j ) {
Complex scc(spinColourCorrelatorResults[2*i+2*n*j]*units, spinColourCorrelatorResults[2*i+2*n*j+1]*units);
lastColourSpinCorrelator(make_pair(i,j),scc);
}
}
}
LorentzVector<Complex> GoSamAmplitude::plusPolarization(const Lorentz5Momentum& p, const Lorentz5Momentum& n, int inc) const {
double pvec[4] = {p.t()/GeV,p.x()/GeV,p.y()/GeV,p.z()/GeV};
double nvec[4] = {n.t()/GeV,n.x()/GeV,n.y()/GeV,n.z()/GeV};
double out[8] ={ };
OLP_Polvec(pvec,nvec,out);
LorentzVector<Complex> res;
Complex a(out[0],out[1]);
res.setT(a);
Complex b(out[2],out[3]);
res.setX(b);
Complex c(out[4],out[5]);
res.setY(c);
Complex d(out[6],out[7]);
res.setZ(d);
if (inc<2)
return res.conjugate();
else
return res;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void GoSamAmplitude::persistentOutput(PersistentOStream & os) const {
os << idpair << idtypepair << processmap << gosamPathInterface
<< gosamSetupInFileNameInterface << gosamBuildScript << gosamPath
<< gosamSourcePath << gosamInstallPath << gosamSetupInFileName
<< orderFileTitle << contractFileTitle
<< contractFileName << orderFileName
<< theCodeExists << theFormOpt << theNinja << isitDR << massiveParticles << theHiggsEff
<< theAccuracyTarget << theMassiveLeptons << theLoopInducedOption
<< doneGoSamInit << doneGoSamInitRun
<< bindir_ << pkgdatadir_ << GoSamPrefix_;
}
void GoSamAmplitude::persistentInput(PersistentIStream & is, int) {
is >> idpair >> idtypepair >> processmap >> gosamPathInterface
>> gosamSetupInFileNameInterface >> gosamBuildScript >> gosamPath
>> gosamSourcePath >> gosamInstallPath >> gosamSetupInFileName
>> orderFileTitle >> contractFileTitle
>> contractFileName >> orderFileName
>> theCodeExists >> theFormOpt >> theNinja >> isitDR >> massiveParticles >> theHiggsEff
>> theAccuracyTarget >> theMassiveLeptons >> theLoopInducedOption
>> doneGoSamInit >> doneGoSamInitRun
>> bindir_ >> pkgdatadir_ >> GoSamPrefix_;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<GoSamAmplitude, MatchboxOLPME> describeHerwigGoSamAmplitude("Herwig::GoSamAmplitude", "HwMatchboxGoSam.so");
void GoSamAmplitude::Init() {
static ClassDocumentation<GoSamAmplitude>
documentation("GoSamAmplitude implements an interface to GoSam.",
"Matrix elements have been calculated using GoSam \\cite{Cullen:2011xs}, \\cite{Cullen:2014yla}",
"%\\cite{Cullen:2011xs}\n"
"\\bibitem{Cullen:2011xs}\n"
"G.~Cullen et al.,\n"
"``GoSam: A Program for Automated One-Loop Calculations,''\n"
"arXiv:1111.6534 [hep-ph].\n"
"%%CITATION = ARXIV:1111.6534;%%\n"
"%\\cite{Cullen:2014yla}\n"
"\\bibitem{Cullen:2014yla}\n"
"G.~Cullen et al.,\n"
"``GoSaam-2.0: a tool for automated one-loop calculations within the Standard Model and beyond,''\n"
"arXiv:1404.7096 [hep-ph].\n"
"%%CITATION = ARXIV:1404.7096;%%");
static Parameter<GoSamAmplitude,string> interfaceProcessPath
("ProcessPath",
"Prefix for the process source code, include files and library produced by GoSam.",
&GoSamAmplitude::gosamPathInterface, "",
false, false);
static Parameter<GoSamAmplitude,string> interfaceSetupInFilename
("SetupInFilename",
"File name of the GoSam infile (typically setup.gosam.in) to be used. If left empty a new setup.gosam.in is created in the location specified in Path",
&GoSamAmplitude::gosamSetupInFileNameInterface, "",
false, false);
static Switch<GoSamAmplitude,bool> interfaceCodeExists
("CodeExists",
"Switch on or off if Code already exists/not exists.",
&GoSamAmplitude::theCodeExists, true, false, false);
static SwitchOption interfaceCodeExistsYes
(interfaceCodeExists,
"Yes",
"Switch True if Code already exists.",
true);
static SwitchOption interfaceCodeExistsNo
(interfaceCodeExists,
"No",
"Switch False if Code has to be build.",
false);
static Switch<GoSamAmplitude,bool> interfaceisitDR
("isDR",
"Switch on or off DR.",
&GoSamAmplitude::isitDR, false, false, false);
static SwitchOption interfaceisitDRYes
(interfaceisitDR,
"Yes",
"Switch True.",
true);
static SwitchOption interfaceisitDRNo
(interfaceisitDR,
"No",
"Switch False.",
false);
static Switch<GoSamAmplitude,bool> interfaceFormOpt
("FormOpt",
"Switch On/Off formopt",
&GoSamAmplitude::theFormOpt, true, false, false);
static SwitchOption interfaceFormOptYes
(interfaceFormOpt,
"Yes",
"Yes",
true);
static SwitchOption interfaceFormOptNo
(interfaceFormOpt,
"No",
"No",
false);
static Switch<GoSamAmplitude,bool> interfaceNinja
("Ninja",
"Switch On/Off for reduction with Ninja. If Off then Samurai is used.",
&GoSamAmplitude::theNinja, true, false, false);
static SwitchOption interfaceNinjaYes
(interfaceNinja,
"Yes",
"Yes",
true);
static SwitchOption interfaceNinjaNo
(interfaceNinja,
"No",
"No",
false);
static Switch<GoSamAmplitude,bool> interfaceHiggsEff
("HiggsEff",
"Switch On/Off for effective higgs model.",
&GoSamAmplitude::theHiggsEff, false, false, false);
static SwitchOption interfaceHiggsEffYes
(interfaceHiggsEff,
"Yes",
"Yes",
true);
static SwitchOption interfaceHiggsEffNo
(interfaceHiggsEff,
"No",
"No",
false);
static Parameter<GoSamAmplitude,string> interfaceBuildScript
("BuildScript",
"File name of a custom build script, which is called between 'autogen.sh'"
"and 'make install'. It can be used for parallelization.",
&GoSamAmplitude::gosamBuildScript, "",
false, false);
static Parameter<GoSamAmplitude,int> interfaceAccuracyTarget
("AccuracyTarget",
"Integer to parametrize the threshold value for the BLHA2 acc parameter, returned by GoSam in the case of "
"sub-processes with one-loop intereference terms or loop induced sub-processes."
"If acc > 10^-AccuracyTarget the corresponding PSP is being discarded. Discarded PSPs are written to file "
"if Debug::level > 1.",
&GoSamAmplitude::theAccuracyTarget, 6, 0, 0,
false, false, Interface::lowerlim);
static Switch<GoSamAmplitude,bool> interfaceMassiveLeptons
("MassiveLeptons",
"If set to Yes, then pass on the light lepton masses - as well as the tau mass - to GoSam."
"Otherwise GoSam will use light leptons of zero mass as default, as well as its own default tau mass.",
&GoSamAmplitude::theMassiveLeptons, false, false, false);
static SwitchOption interfaceMassiveLeptonsNo
(interfaceMassiveLeptons,
"No",
"No",
false);
static SwitchOption interfaceMassiveLeptonsYes
(interfaceMassiveLeptons,
"Yes",
"Yes",
true);
static Switch<GoSamAmplitude,int> interfaceLoopInducedOption
("LoopInducedOption",
"Options for the GoSam interface, in the case that a loop induced process is being considered. The default "
"option is 0, for which only the squared one-loop amplitude in the Standard Model is being considered. All "
"other options consider additional contributions from a model with an effective interaction, which lead to "
"the same final state, such as the squared effective amplitude, or the interference term between the one- "
"loop amplitude in the Standard Model and the effective amplitude, or any additive combinations therefrom. "
"In order to use those options an appropriate model has to be used.",
&GoSamAmplitude::theLoopInducedOption, 0, false, false);
static SwitchOption interfaceLoopInducedOptionLI2
(interfaceLoopInducedOption,
"LI2",
"Only consider the squared one-loop amplitude in the Standard Model.",
0);
static SwitchOption interfaceLoopInducedOptionEff2
(interfaceLoopInducedOption,
"Eff2",
"Only consider the squared effective amplitude.",
1);
static SwitchOption interfaceLoopInducedOptionLIEffInterference
(interfaceLoopInducedOption,
"LIEffInterference",
"Only consider the interference term between the one-loop amplitude "
"in the Standard Model and the effective amplitude.",
2);
static SwitchOption interfaceLoopInducedOptionLI2plusEff2
(interfaceLoopInducedOption,
"LI2plusEff2",
"Consider the sum of the squared one-loop amplitude in the Standard "
"Model plus the squared effective amplitude.",
3);
static SwitchOption interfaceLoopInducedOptionLI2plusLIEffInterference
(interfaceLoopInducedOption,
"LI2plusEffInterference",
"Consider the sum of the squared one-loop amplitude in the Standard "
"Model plus the interference term between the one-loop amplitude in "
"the Standard Model and the effective amplitude.",
4);
static SwitchOption interfaceLoopInducedOptionEff2plusLIEffInterference
(interfaceLoopInducedOption,
"Eff2plusEffInterference",
"Consider the sum of the squared effective amplitude plus the inter- "
"ference term between the one-loop amplitude in the Standard Model "
"and the effective amplitude.",
5);
static SwitchOption interfaceLoopInducedOptionAllAdditions
(interfaceLoopInducedOption,
"AllAdditions",
"Consider the sum of the squared one-loop amplitude in the Standard "
"Model plus all other contributions, which come with the effective "
"Model.",
6);
static Parameter<GoSamAmplitude,string> interfaceBinDir
("BinDir",
"The location for the installed executable",
&GoSamAmplitude::bindir_, string(HERWIG_BINDIR),
false, false);
static Parameter<GoSamAmplitude,string> interfacePKGDATADIR
("DataDir",
"The location for the installed Herwig data files",
&GoSamAmplitude::pkgdatadir_, string(HERWIG_PKGDATADIR),
false, false);
static Parameter<GoSamAmplitude,string> interfaceGoSamPrefix
("GoSamPrefix",
"The prefix for the location of GoSam",
&GoSamAmplitude::GoSamPrefix_, string(GOSAM_PREFIX),
false, false);
}
diff --git a/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.h b/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.h
--- a/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.h
+++ b/MatrixElement/Matchbox/External/GoSam/GoSamAmplitude.h
@@ -1,329 +1,318 @@
// -*- C++ -*-
//
// GoSamAmplitude.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_GoSamAmplitude_H
#define Herwig_GoSamAmplitude_H
//
// This is the declaration of the GoSamAmplitude class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxOLPME.h"
#include "ThePEG/Utilities/DynamicLoader.h"
namespace Herwig {
using namespace ThePEG;
class gosamprocinfo{
public:
gosamprocinfo(){};
gosamprocinfo(int HID,int GID, string procstr,string typestr):
theHOlpId(HID),theGOlpId(GID),theProcstr(procstr),theTypestr(typestr){
}
~gosamprocinfo(){}
int HID() const {return theHOlpId;}
int GID() const {return theGOlpId;}
string Pstr() const {return theProcstr;}
string Tstr() const {return theTypestr;}
void setGID(int g){theGOlpId=g;}
void setOAs(int i){ orderAlphas=i;}
int orderAs(){return orderAlphas;}
void setOAew(int j){ orderAlphaew=j;}
int orderAew(){return orderAlphaew;}
private:
int theHOlpId;
int theGOlpId;
string theProcstr;
string theTypestr;
int orderAlphas;
int orderAlphaew;
public:
void persistentOutput(PersistentOStream & os) const{os<<theHOlpId<<theGOlpId<<theProcstr<<theTypestr<<orderAlphas<<orderAlphaew;}
void persistentInput(PersistentIStream &is) {is>>theHOlpId>>theGOlpId>>theProcstr>>theTypestr>>orderAlphas>>orderAlphaew;}
};
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief GoSamAmplitude implements an interface to GoSam
*/
class GoSamAmplitude: public MatchboxOLPME {
public:
- /** @name Standard constructors and destructors. */
- //@{
-
/**
* The default constructor.
*/
GoSamAmplitude();
- /**
- * The destructor.
- */
- virtual ~GoSamAmplitude();
-
- //@}
-
-
public:
virtual void fillOrderFile(const map<pair<Process,int>,int>& procs, string OrderFileName);
virtual bool isCS() const { return false; }
virtual bool isExpanded() const { return true; }
virtual bool isBDK() const { return false; }
virtual bool isDR() const { return isitDR; }
virtual bool isDRbar() const {return false;}
/**
* Start the one loop provider, if appropriate, giving order and
* contract files
*/
virtual void signOLP(const string&, const string&);
virtual bool checkOLPContract(string contractFileName);
/**
* Return true, if this amplitude already includes symmetry factors
* for identical outgoing particles.
*/
// virtual bool hasFinalStateSymmetry() const { return true; }
virtual bool hasFinalStateSymmetry() const { return false; }
virtual bool buildGoSam();
/**
* Start the one loop provider, if appropriate
*/
virtual void startOLP(const string&, int& status);
/**
* Return the value of the dimensional regularization
* parameter. Note that renormalization scale dependence is fully
* restored in DipoleIOperator.
*/
// virtual Energy2 mu2() const { return lastSHat(); }
/**
* Start the one loop provider, if appropriate. This default
* implementation writes an BLHA 2.0 order file and starts the OLP
*/
virtual bool startOLP(const map<pair<Process,int>,int>& procs);
/**
* Call OLP_EvalSubProcess and fill in the results
*/
void evalSubProcess() const;
/**
* Fill in results for the given colour correlator
*/
virtual void evalColourCorrelator(pair<int,int> ij) const;
/**
* Return a positive helicity polarization vector for a gluon of
* momentum p (with reference vector n) to be used when evaluating
* spin correlations.
*/
virtual LorentzVector<Complex> plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n, int inc) const;
/**
* Fill in results for the given colour/spin correlator
*/
virtual void evalSpinColourCorrelator(pair<int,int> ij) const;
void getids() const;
int accuracyTargetNegExp() const { return theAccuracyTarget; }
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();
//@}
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.
*/
GoSamAmplitude & operator=(const GoSamAmplitude &) = delete;
/**
* Store colour correlator results
*/
mutable vector<double> colourCorrelatorResults;
/**
* Store spin colour correlator results
*/
mutable vector<double> spinColourCorrelatorResults;
/**
* first is the olp id from herwig, second the answer from gosam
*/
mutable vector<int> idpair;
/**
* first is the olp id from herwig, second the amplitude type
*/
mutable vector<string> idtypepair;
/**
* Map to store all processes handled by this Amplitude
*/
map<int , gosamprocinfo > processmap;
mutable string gosamPathInterface;
mutable string gosamSetupInFileNameInterface;
mutable string gosamBuildScript;
mutable string gosamPath;
mutable string gosamSourcePath;
mutable string gosamInstallPath;
mutable string gosamSetupInFileName;
mutable string orderFileTitle;
mutable string contractFileTitle;
mutable string contractFileName;
mutable string orderFileName;
mutable string accuracyFileTitle;
mutable string accuracyFile;
int theAccuracyTarget;
bool theCodeExists;
bool theFormOpt;
bool theNinja;
bool theHiggsEff;
bool theMassiveLeptons;
int theLoopInducedOption;
bool isitDR;
mutable bool doneGoSamInit;
mutable bool doneGoSamInitRun;
/**
* The PDG codes of those quarks with mass
*/
vector<int> massiveParticles; //theMassiveParticles;
/**
* Method to create the setup.in file for GoSam
*/
void setupGoSamIn(string setupGoSamInFile);
protected:
/**
* Location of the installed executables
*/
string bindir_;
/**
* Location of the data files
*/
string pkgdatadir_;
/**
* Location of GOSAM
*/
string GoSamPrefix_;
}; // end "class GoSamAmplitude: public MatchboxOLPME"
inline PersistentOStream& operator<<(PersistentOStream& os, const gosamprocinfo& p) {
p.persistentOutput(os); return os;
}
inline PersistentIStream& operator>>(PersistentIStream& is, gosamprocinfo& p) {
p.persistentInput(is); return is;
}
} // end "namespace Herwig"
#endif /* Herwig_GoSamAmplitude_H */
diff --git a/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.cc b/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.cc
--- a/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.cc
+++ b/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.cc
@@ -1,310 +1,308 @@
// -*- C++ -*-
//
// NJetsAmplitude.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the NJetsAmplitude class.
//
#include "NJetsAmplitude.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Utilities/DynamicLoader.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
#include "njet.h"
#include <cstdlib>
#ifndef NJET_PREFIX
#error Makefile.am needs to define NJET_PREFIX
#endif
#ifndef NJET_LIBS
#error Makefile.am needs to define NJET_LIBS
#endif
using namespace Herwig;
NJetsAmplitude::NJetsAmplitude() : NJetsPrefix_(NJET_PREFIX),
NJetsLibs_(NJET_LIBS) {}
-NJetsAmplitude::~NJetsAmplitude() {}
-
IBPtr NJetsAmplitude::clone() const {
return new_ptr(*this);
}
IBPtr NJetsAmplitude::fullclone() const {
return new_ptr(*this);
}
void NJetsAmplitude::signOLP(const string& order, const string& contract) {
string cmd = NJetsPrefix_+"/bin/njet.py -o " + contract + " " + order;
std::system(cmd.c_str());
}
void NJetsAmplitude::startOLP(const string& contract, int& status) {
NJet::LH_OLP::OLP_Start(contract.c_str(), &status);
if ( status != 1 )
return;
status = 0;
static double zero = 0.0;
double param = 0.0;
param = SM().alphaEMMZ();
NJet::LH_OLP::OLP_SetParameter("alpha",&param,&zero,&status);
if ( status != 1 )
return;
param = getParticleData(ParticleID::Z0)->hardProcessMass()/GeV;
NJet::LH_OLP::OLP_SetParameter("mass(23)",&param,&zero,&status);
if ( status != 1 )
return;
param = getParticleData(ParticleID::Wplus)->hardProcessMass()/GeV;
NJet::LH_OLP::OLP_SetParameter("mass(24)",&param,&zero,&status);
if ( status != 1 )
return;
param = getParticleData(ParticleID::Z0)->hardProcessWidth()/GeV;
NJet::LH_OLP::OLP_SetParameter("width(23)",&param,&zero,&status);
if ( status != 1 )
return;
param = getParticleData(ParticleID::Wplus)->hardProcessWidth()/GeV;
NJet::LH_OLP::OLP_SetParameter("width(24)",&param,&zero,&status);
if ( status != 1 )
return;
param = SM().sin2ThetaW();
NJet::LH_OLP::OLP_SetParameter("sw2",&param,&zero,&status);
didStartOLP() = true;
}
void NJetsAmplitude::loadNJET() {
if ( ! (DynamicLoader::load(NJetsLibs_+"/libnjet2.so") ||
DynamicLoader::load("libnjet2.so") ||
DynamicLoader::load(NJetsLibs_+"/libnjet2.dylib") ||
DynamicLoader::load("libnjet2.dylib") ) )
throw Exception() << "NJetsAmplitude: Failed to load libnjet2.so\n"
<< DynamicLoader::lastErrorMessage
<< Exception::runerror;
}
bool NJetsAmplitude::startOLP(const map<pair<Process,int>,int>& procs) {
loadNJET();
// TODO throw exception on massive leptons in procs
string orderFileName = factory()->buildStorage() + name() + ".OLPOrder.lh";
ofstream orderFile(orderFileName.c_str());
olpOrderFileHeader(orderFile);
orderFile << "NJetReturnAccuracy yes\n"
<< "NJetRenormalize yes\n"
#if NJET_VERSION > 1023
<< "SetParameter qcd(nf) " << factory()->nLight() << "\n"; // NJet >= 2.1.0:
#else
<< "NJetNf " << factory()->nLight() << "\n"; // NJet <=2.0.0
#endif
olpOrderFileProcesses(orderFile,procs);
orderFile << flush;
orderFile.close();
string contractFileName = factory()->buildStorage() + name() + ".OLPContract.lh";
signOLP(orderFileName, contractFileName);
int status = -1;
startOLP(contractFileName,status);
if ( status != 1 )
return false;
return true;
}
LorentzVector<Complex> NJetsAmplitude::plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n,
int inc) const {
double pvec[4] = {p.t()/GeV,p.x()/GeV,p.y()/GeV,p.z()/GeV};
double nvec[4] = {n.t()/GeV,n.x()/GeV,n.y()/GeV,n.z()/GeV};
double out[8] ={ };
NJet::LH_OLP::OLP_Polvec(pvec,nvec,out);
LorentzVector<Complex> res;
Complex a(out[0],out[1]);
res.setT(a);
Complex b(out[2],out[3]);
res.setX(b);
Complex c(out[4],out[5]);
res.setY(c);
Complex d(out[6],out[7]);
res.setZ(d);
if (inc<2)
return res.conjugate();
else
return res;
}
void NJetsAmplitude::evalSubProcess() const {
useMe();
double units = pow(lastSHat()/GeV2,mePartonData().size()-4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double as;
if (!hasRunningAlphaS()) as = SM().alphaS();
else if (hasRunningAlphaS()) as = lastAlphaS();
double scale = sqrt(mu2()/GeV2);
double out[7]={};
int id =
olpId()[ProcessType::oneLoopInterference] ?
olpId()[ProcessType::oneLoopInterference] :
olpId()[ProcessType::treeME2];
NJet::LH_OLP::OLP_EvalSubProcess(id, olpMomenta(), scale, &as, out);
if ( olpId()[ProcessType::oneLoopInterference] ) {
if(calculateTreeME2())lastTreeME2(out[3]*units);
lastOneLoopInterference(out[2]*units);
lastOneLoopPoles(pair<double,double>(out[0]*units,out[1]*units));
} else if ( olpId()[ProcessType::treeME2] ) {
lastTreeME2(out[0]*units);
} else assert(false);
}
void NJetsAmplitude::evalColourCorrelator(pair<int,int>) const {
double units = pow(lastSHat()/GeV2,mePartonData().size()-4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double as;
if (!hasRunningAlphaS()) as = SM().alphaS();
else if (hasRunningAlphaS()) as = lastAlphaS();
double scale = sqrt(mu2()/GeV2);
int n = lastXComb().meMomenta().size();
colourCorrelatorResults.resize(n*(n-1)/2);
NJet::LH_OLP::OLP_EvalSubProcess(olpId()[ProcessType::colourCorrelatedME2],
olpMomenta(), scale, &as, &colourCorrelatorResults[0]);
for ( int i = 0; i < n; ++i )
for ( int j = i+1; j < n; ++j ) {
lastColourCorrelator(make_pair(i,j),colourCorrelatorResults[i+j*(j-1)/2]*units);
}
}
void NJetsAmplitude::evalSpinColourCorrelator(pair<int,int>) const {
double units = pow(lastSHat()/GeV2,mePartonData().size()-4.);
fillOLPMomenta(lastXComb().meMomenta(),mePartonData(),reshuffleMasses());
double as;
if (!hasRunningAlphaS()) as = SM().alphaS();
else if (hasRunningAlphaS()) as = lastAlphaS();
double scale = sqrt(mu2()/GeV2);
int n = lastXComb().meMomenta().size();
spinColourCorrelatorResults.resize(2*n*n);
NJet::LH_OLP::OLP_EvalSubProcess(olpId()[ProcessType::spinColourCorrelatedME2],
olpMomenta(), scale, &as, &spinColourCorrelatorResults[0]);
for ( int i = 0; i < n; ++i )
for ( int j = 0; j < n; ++j ) {
if ( i == j || mePartonData()[i]->id() != 21 )
continue;
Complex scc(spinColourCorrelatorResults[2*i+2*n*j]*units,
spinColourCorrelatorResults[2*i+2*n*j+1]*units);
lastColourSpinCorrelator(make_pair(i,j),scc);
}
}
void NJetsAmplitude::doinit() {
loadNJET();
MatchboxOLPME::doinit();
}
void NJetsAmplitude::doinitrun() {
loadNJET();
MatchboxOLPME::doinitrun();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void NJetsAmplitude::persistentOutput(PersistentOStream & os) const {
os << colourCorrelatorResults << spinColourCorrelatorResults
<< NJetsPrefix_ << NJetsLibs_;
}
void NJetsAmplitude::persistentInput(PersistentIStream & is, int) {
is >> colourCorrelatorResults >> spinColourCorrelatorResults
>> NJetsPrefix_ >> NJetsLibs_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<NJetsAmplitude,MatchboxOLPME>
describeHerwigNJetsAmplitude("Herwig::NJetsAmplitude", "HwMatchboxNJet.so");
void NJetsAmplitude::Init() {
static ClassDocumentation<NJetsAmplitude> documentation
("NJetsAmplitude implements an interface to NJets.",
"Matrix elements have been calculated using NJet \\cite{Badger:2012pg}",
"%\\cite{Badger:2012pg}\n"
"\\bibitem{Badger:2012pg}\n"
"S.~Badger et al.,\n"
"``Numerical evaluation of virtual corrections to multi-jet production in massless QCD,''\n"
"arXiv:1209.0100 [hep-ph].\n"
"%%CITATION = ARXIV:1209.0100;%%");
static Parameter<NJetsAmplitude,string> interfaceNJetsPrefix
("NJetsPrefix",
"The prefix for the location of NJets",
&NJetsAmplitude::NJetsPrefix_, string(NJET_PREFIX),
false, false);
static Parameter<NJetsAmplitude,string> interfaceNJetsLibs
("NJetsLibs",
"The location of the NJets library",
&NJetsAmplitude::NJetsLibs_, string(NJET_LIBS),
false, false);
}
diff --git a/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.h b/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.h
--- a/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.h
+++ b/MatrixElement/Matchbox/External/NJet/NJetsAmplitude.h
@@ -1,203 +1,195 @@
// -*- C++ -*-
//
// NJetsAmplitude.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_NJetsAmplitude_H
#define Herwig_NJetsAmplitude_H
//
// This is the declaration of the NJetsAmplitude class.
//
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxOLPME.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief NJetsAmplitude implements an interface to NJets
*/
class NJetsAmplitude: public MatchboxOLPME {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
NJetsAmplitude();
- /**
- * The destructor.
- */
- virtual ~NJetsAmplitude();
- //@}
-
public:
/**
* Return true, if this amplitude already includes averaging over
* incoming parton's quantum numbers.
*/
virtual bool hasInitialAverage() const { return false; }
/**
* Return true, if this amplitude already includes symmetry factors
* for identical outgoing particles.
*/
virtual bool hasFinalStateSymmetry() const { return false; }
/**
* Start the one loop provider, if appropriate, giving order and
* contract files
*/
virtual void signOLP(const string&, const string&);
/**
* Start the one loop provider, if appropriate
*/
virtual void startOLP(const string&, int& status);
/**
* Start the one loop provider, if appropriate. This default
* implementation writes an BLHA 2.0 order file and starts the OLP
*/
virtual bool startOLP(const map<pair<Process,int>,int>& procs);
/**
* Call OLP_EvalSubProcess and fill in the results
*/
virtual void evalSubProcess() const;
/**
* Fill in results for the given colour correlator
*/
virtual void evalColourCorrelator(pair<int,int> ij) const;
/**
* Return a positive helicity polarization vector for a gluon of
* momentum p (with reference vector n) to be used when evaluating
* spin correlations.
*/
virtual LorentzVector<Complex> plusPolarization(const Lorentz5Momentum& p,
const Lorentz5Momentum& n,
int id = -1) const;
/**
* Fill in results for the given colour/spin correlator
*/
virtual void evalSpinColourCorrelator(pair<int,int> ij) 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();
//@}
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.
*/
NJetsAmplitude & operator=(const NJetsAmplitude &) = delete;
/**
* Store colour correlator results
*/
mutable vector<double> colourCorrelatorResults;
/**
* Store spin colour correlator results
*/
mutable vector<double> spinColourCorrelatorResults;
/**
* Location of NJETs
*/
string NJetsPrefix_;
/**
* Location of NJET librarys
*/
string NJetsLibs_;
/**
* Load the NJET library
*/
void loadNJET();
};
}
#endif /* Herwig_NJetsAmplitude_H */
diff --git a/MatrixElement/Matchbox/MatchboxFactory.cc b/MatrixElement/Matchbox/MatchboxFactory.cc
--- a/MatrixElement/Matchbox/MatchboxFactory.cc
+++ b/MatrixElement/Matchbox/MatchboxFactory.cc
@@ -1,2106 +1,2104 @@
// -*- C++ -*-
//
// MatchboxFactory.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MatchboxFactory class.
//
#include "MatchboxFactory.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Utilities/StringUtils.h"
#include "ThePEG/Repository/Repository.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Handlers/EventHandler.h"
#include "ThePEG/Handlers/SamplerBase.h"
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
#include "Herwig/MatrixElement/Matchbox/Utility/SU2Helper.h"
#include "Herwig/API/RunDirectories.h"
#include "Herwig/Utilities/Progress.h"
#include <iterator>
using std::ostream_iterator;
using namespace Herwig;
using std::ostream_iterator;
MatchboxFactory::MatchboxFactory()
: SubProcessHandler(), theNLight(0),
theOrderInAlphaS(0), theOrderInAlphaEW(0),
theBornContributions(true), theVirtualContributions(true),
theRealContributions(true), theIndependentVirtuals(false),
theIndependentPKs(false),
theFactorizationScaleFactor(1.0), theRenormalizationScaleFactor(1.0),
theFixedCouplings(false), theFixedQEDCouplings(false), theVetoScales(false),
theDipoleSet(0), theVerbose(false), theInitVerbose(false),
theSubtractionData(""), theSubtractionPlotType(1), theSubtractionScatterPlot(false),
thePoleData(""), theRealEmissionScales(false), theAllProcesses(false),
theMECorrectionsOnly(false), theLoopSimCorrections(false), ranSetup(false),
theFirstPerturbativePDF(true), theSecondPerturbativePDF(true),
inProductionMode(false), theSpinCorrelations(false),theAlphaParameter(1.),
theEnforceChargeConservation(true), theEnforceColourConservation(false),
theEnforceLeptonNumberConservation(false), theEnforceQuarkNumberConservation(false),
theLeptonFlavourDiagonal(false), theQuarkFlavourDiagonal(false) {}
-MatchboxFactory::~MatchboxFactory() {}
-
Ptr<MatchboxFactory>::tptr MatchboxFactory::theCurrentFactory = Ptr<MatchboxFactory>::tptr();
bool& MatchboxFactory::theIsMatchboxRun() {
static bool flag = false;
return flag;
}
IBPtr MatchboxFactory::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxFactory::fullclone() const {
return new_ptr(*this);
}
void MatchboxFactory::prepareME(Ptr<MatchboxMEBase>::ptr me) {
Ptr<MatchboxAmplitude>::ptr amp =
dynamic_ptr_cast<Ptr<MatchboxAmplitude>::ptr>((*me).amplitude());
me->matchboxAmplitude(amp);
if ( phasespace() && !me->phasespace() )
me->phasespace(phasespace());
if ( scaleChoice() && !me->scaleChoice() )
me->scaleChoice(scaleChoice());
if ( !reweighters().empty() ) {
for ( vector<ReweightPtr>::const_iterator rw = reweighters().begin();
rw != reweighters().end(); ++rw )
me->addReweighter(*rw);
}
if ( !preweighters().empty() ) {
for ( vector<ReweightPtr>::const_iterator rw = preweighters().begin();
rw != preweighters().end(); ++rw )
me->addPreweighter(*rw);
}
}
string pid(const PDVector& key) {
ostringstream res;
res << "[" << key[0]->PDGName() << ","
<< key[1]->PDGName() << "->";
for ( PDVector::const_iterator k =
key.begin() + 2; k != key.end(); ++k )
res << (**k).PDGName() << (k != --key.end() ? "," : "");
res << "]";
return res.str();
}
vector<Ptr<MatchboxMEBase>::ptr> MatchboxFactory::
makeMEs(const vector<string>& proc, unsigned int orderas, bool virt) {
generator()->log() << "determining subprocesses for ";
copy(proc.begin(),proc.end(),ostream_iterator<string>(generator()->log()," "));
generator()->log() << "\n" << flush;
map<Ptr<MatchboxAmplitude>::ptr,set<Process> > ampProcs;
map<Process,set<Ptr<MatchboxAmplitude>::ptr> > procAmps;
set<PDVector> processes = makeSubProcesses(proc);
set<PDVector> colouredProcesses;
for ( set<PDVector>::const_iterator pr = processes.begin();
pr != processes.end(); ++pr ) {
for ( PDVector::const_iterator pp = pr->begin();
pp != pr->end(); ++pp ) {
if ( (**pp).coloured() ) {
colouredProcesses.insert(*pr);
break;
}
}
}
if ( colouredProcesses.size() != processes.size() &&
(virtualContributions() || realContributions()) ) {
// NLO not working for non coloured legs
throw Exception()
<< "Found processes without coloured legs.\n"
<< "We currently do not support NLO corrections for those processes.\n"
<< "Please switch to a setup for LO production."
<< Exception::runerror;
}
// detect external particles with non-zero width for the hard process
bool trouble = false;
string troubleMaker;
for ( set<PDVector>::const_iterator pr = processes.begin();
pr != processes.end(); ++pr ) {
for ( PDVector::const_iterator pp = pr->begin();
pp != pr->end(); ++pp ) {
if ( (**pp).hardProcessWidth() != ZERO ) {
trouble = true;
troubleMaker = (**pp).PDGName();
break;
}
}
}
if ( trouble ) {
throw Exception()
<< "MatchboxFactory::makeMEs(): Particle '"
<< troubleMaker << "' appears as external\nprocess leg with non-zero "
<< "width to be used in the hard process calculation.\n"
<< "Please check your setup and consider setting HardProcessWidth to zero."
<< Exception::runerror;
}
vector<Ptr<MatchboxAmplitude>::ptr> matchAmplitudes;
unsigned int lowestAsOrder =
allProcesses() ? 0 : orderas;
unsigned int highestAsOrder = orderas;
unsigned int lowestAeOrder =
allProcesses() ? 0 : orderInAlphaEW();
unsigned int highestAeOrder = orderInAlphaEW();
for ( unsigned int oas = lowestAsOrder; oas <= highestAsOrder; ++oas ) {
for ( unsigned int oae = lowestAeOrder; oae <= highestAeOrder; ++oae ) {
for ( vector<Ptr<MatchboxAmplitude>::ptr>::const_iterator amp
= amplitudes().begin(); amp != amplitudes().end(); ++amp ) {
if ( !theSelectedAmplitudes.empty() ) {
if ( find(theSelectedAmplitudes.begin(),theSelectedAmplitudes.end(),*amp)
== theSelectedAmplitudes.end() )
continue;
}
if ( !theDeselectedAmplitudes.empty() ) {
if ( find(theDeselectedAmplitudes.begin(),theDeselectedAmplitudes.end(),*amp)
!= theDeselectedAmplitudes.end() )
continue;
}
(**amp).orderInGs(oas);
(**amp).orderInGem(oae);
if ( (**amp).orderInGs() != oas ||
(**amp).orderInGem() != oae ) {
continue;
}
matchAmplitudes.push_back(*amp);
}
}
}
size_t combinations = processes.size()*matchAmplitudes.size();
size_t procCount = 0;
generator()->log() << "building matrix elements." << flush;
progress_display progressBar{ combinations, generator()->log() };
for ( unsigned int oas = lowestAsOrder; oas <= highestAsOrder; ++oas ) {
for ( unsigned int oae = lowestAeOrder; oae <= highestAeOrder; ++oae ) {
for ( vector<Ptr<MatchboxAmplitude>::ptr>::const_iterator amp
= matchAmplitudes.begin(); amp != matchAmplitudes.end(); ++amp ) {
(**amp).orderInGs(oas);
(**amp).orderInGem(oae);
for ( set<PDVector>::const_iterator p = processes.begin();
p != processes.end(); ++p ) {
++progressBar;
if ( !(**amp).canHandle(*p,this,virt) )
continue;
if ( (**amp).isExternal() )
externalAmplitudes().insert(*amp);
++procCount;
Process proc(*p,oas,oae);
ampProcs[*amp].insert(proc);
procAmps[proc].insert(*amp);
}
}
}
}
generator()->log() << flush;
bool clash = false;
for ( map<Process,set<Ptr<MatchboxAmplitude>::ptr> >::const_iterator check =
procAmps.begin(); check != procAmps.end(); ++check ) {
if ( check->second.size() > 1 ) {
clash = true;
generator()->log() << "Several different amplitudes have been found for: "
<< check->first.legs[0]->PDGName() << " "
<< check->first.legs[1]->PDGName() << " -> ";
for ( PDVector::const_iterator p = check->first.legs.begin() + 2;
p != check->first.legs.end(); ++p )
generator()->log() << (**p).PDGName() << " ";
generator()->log() << "at alpha_s^" << check->first.orderInAlphaS
<< " and alpha_ew^" << check->first.orderInAlphaEW
<< "\n";
generator()->log() << "The following amplitudes claim responsibility:\n";
for ( set<Ptr<MatchboxAmplitude>::ptr>::const_iterator a = check->second.begin();
a != check->second.end(); ++a ) {
generator()->log() << (**a).name() << " ";
}
generator()->log() << "\n";
}
}
if ( clash ) {
throw Exception() << "MatchboxFactory: Ambiguous amplitude setup - please check your input files.\n"
<< "To avoid this problem use the SelectAmplitudes or DeselectAmplitudes interfaces.\n"
<< Exception::runerror;
}
bool canDoSpinCorrelations = true;
vector<Ptr<MatchboxMEBase>::ptr> res;
for ( map<Ptr<MatchboxAmplitude>::ptr,set<Process> >::const_iterator
ap = ampProcs.begin(); ap != ampProcs.end(); ++ap ) {
canDoSpinCorrelations &= ap->first->canFillRhoMatrix();
for ( set<Process>::const_iterator m = ap->second.begin();
m != ap->second.end(); ++m ) {
Ptr<MatchboxMEBase>::ptr me = ap->first->makeME(m->legs);
me->subProcess() = *m;
me->amplitude(ap->first);
me->matchboxAmplitude(ap->first);
prepareME(me);
string pname = "ME" + pid(m->legs);
if ( ! (generator()->preinitRegister(me,pname) ) )
throw Exception() << "MatchboxFactory: Matrix element " << pname << " already existing."
<< Exception::runerror;
if ( me->diagrams().empty() )continue;
res.push_back(me);
if ( theFirstPerturbativePDF )
theIncoming.insert(m->legs[0]->id());
if ( theSecondPerturbativePDF )
theIncoming.insert(m->legs[1]->id());
}
}
if ( spinCorrelations() && !canDoSpinCorrelations ) {
generator()->log() << "Warning: Spin correlations have been requested, but no amplitude is "
<< "capable of performing these.\n";
theSpinCorrelations = false;
}
generator()->log() << "created "
<< procCount << " subprocesses.\n";
generator()->log() << "---------------------------------------------------\n"
<< flush;
return res;
}
int MatchboxFactory::orderOLPProcess(const Process& proc,
Ptr<MatchboxAmplitude>::tptr amp,
int type) {
map<pair<Process,int>,int>& procs =
olpProcesses()[amp];
map<pair<Process,int>,int>::const_iterator it =
procs.find(make_pair(proc,type));
if ( it != procs.end() )
return it->second;
int id = procs.size();
procs[make_pair(proc,type)] = id + 1;
return id + 1;
}
void MatchboxFactory::productionMode() {
if ( inProductionMode )
return;
if ( !bornContributions() && !virtualContributions() && !realContributions() )
throw Exception() << "MatchboxFactory: At least one cross section contribution needs to be enabled.\n"
<< "Please check your setup.\n"
<< Exception::runerror;
bool needTrueVirtuals =
virtualContributions() && !meCorrectionsOnly() && !loopSimCorrections();
for ( vector<Ptr<MatchboxAmplitude>::ptr>::iterator amp
= amplitudes().begin(); amp != amplitudes().end(); ++amp ) {
if ( !needTrueVirtuals && (**amp).oneLoopAmplitude() ) {
Repository::clog() << "One-loop contributions from '"
<< (**amp).name()
<< "' are not required and will be disabled.\n"
<< flush;
(**amp).disableOneLoop();
}
}
if ( subtractionData() != "" && !subProcessGroups() ) {
throw Exception() << "MatchboxFactory: Plain NLO settings are required for subtraction checks.\n"
<< "Please check your setup.\n"
<< Exception::runerror;
}
if ( showerApproximation() && !virtualContributions() && !realContributions() ) {
Repository::clog() << "Warning: Matching requested for LO run. Matching disabled.\n" << flush;
showerApproximation(Ptr<ShowerApproximation>::tptr());
}
if ( showerApproximation() && (subtractionData() != "" || subProcessGroups()) ) {
Repository::clog() << "Warning: Matching requested for plain NLO run. Matching disabled.\n" << flush;
showerApproximation(Ptr<ShowerApproximation>::tptr());
}
if ( showerApproximation() ) {
if ( spinCorrelations() && !showerApproximation()->hasSpinCorrelations() ) {
Repository::clog() << "Warning: Spin correlations have been requested but the matching "
<< "object is not capable of these. Spin correlations will be turned of.\n"
<< flush;
theSpinCorrelations = false;
}
}
inProductionMode = true;
}
void MatchboxFactory::setup() {
useMe();
if ( !ranSetup ) {
if ( !inProductionMode )
throw Exception() << "MatchboxFactory: The MatchboxFactory object '"
<< name() << "' has not been switched to production mode.\n"
<< "Did you use 'do "
<< name() << ":ProductionMode' before isolating the event generator?\n"
<< Exception::runerror;
olpProcesses().clear();
externalAmplitudes().clear();
theHighestVirtualsize = 0;
theIncoming.clear();
bool needTrueVirtuals =
virtualContributions() && !meCorrectionsOnly() && !loopSimCorrections();
if ( bornMEs().empty() ) {
if ( particleGroups().find("j") == particleGroups().end() )
throw Exception() << "MatchboxFactory: Could not find a jet particle group named 'j'"
<< Exception::runerror;
// rebind the particle data objects
for ( map<string,PDVector>::iterator g = particleGroups().begin();
g != particleGroups().end(); ++g )
for ( PDVector::iterator p = g->second.begin();
p != g->second.end(); ++p ) {
#ifndef NDEBUG
long checkid = (**p).id();
#endif
*p = getParticleData((**p).id());
assert((**p).id() == checkid);
}
const PDVector& partons = particleGroups()["j"];
unsigned int nl = 0;
for ( PDVector::const_iterator p = partons.begin();
p != partons.end(); ++p ) {
if ( abs((**p).id()) < 7 && (**p).hardProcessMass() == ZERO )
++nl;
if ( (**p).id() > 0 && (**p).id() < 7 && (**p).hardProcessMass() == ZERO )
nLightJetVec( (**p).id() );
if ( (**p).id() > 0 && (**p).id() < 7 && (**p).hardProcessMass() != ZERO )
nHeavyJetVec( (**p).id() );
}
nLight(nl/2);
if ( particleGroups().find("p") == particleGroups().end() )
throw Exception() << "MatchboxFactory: Could not find a hadron particle group named 'p'"
<< Exception::runerror;
const PDVector& partonsInP = particleGroups()["p"];
for ( PDVector::const_iterator pip = partonsInP.begin();
pip != partonsInP.end(); ++pip ) {
if ( (**pip).id() > 0 && (**pip).id() < 7 && (**pip).hardProcessMass() == ZERO )
nLightProtonVec( (**pip).id() );
}
vector<Ptr<MatchboxMEBase>::ptr> mes;
for ( vector<vector<string> >::const_iterator p = processes.begin();
p != processes.end(); ++p ) {
if( needTrueVirtuals ) {
theHighestVirtualsize = max(theHighestVirtualsize,(int((*p).size())));
}
mes = makeMEs(*p,orderInAlphaS(),needTrueVirtuals);
copy(mes.begin(),mes.end(),back_inserter(bornMEs()));
if ( realContributions() || meCorrectionsOnly() ||
(showerApproximation() && virtualContributions()) ||
(showerApproximation() && loopSimCorrections()) ) {
if ( realEmissionProcesses.empty() ) {
vector<string> rproc = *p;
rproc.push_back("j");
mes = makeMEs(rproc,orderInAlphaS()+1,false);
copy(mes.begin(),mes.end(),back_inserter(realEmissionMEs()));
}
}
}
if ( realContributions() || meCorrectionsOnly() ||
(showerApproximation() && virtualContributions()) ||
(showerApproximation() && loopSimCorrections()) ) {
if ( !realEmissionProcesses.empty() ) {
for ( vector<vector<string> >::const_iterator q =
realEmissionProcesses.begin(); q != realEmissionProcesses.end(); ++q ) {
mes = makeMEs(*q,orderInAlphaS()+1,false);
copy(mes.begin(),mes.end(),back_inserter(realEmissionMEs()));
}
}
}
}
if ( loopInducedMEs().empty() ) {
for ( vector<vector<string> >::const_iterator p = loopInducedProcesses.begin();
p != loopInducedProcesses.end(); ++p ) {
vector<Ptr<MatchboxMEBase>::ptr> mes = makeMEs(*p,orderInAlphaS(),false);
copy(mes.begin(),mes.end(),back_inserter(loopInducedMEs()));
}
}
if( bornMEs().empty() && realEmissionMEs().empty() && loopInducedMEs().empty() )
throw Exception() << "MatchboxFactory: No matrix elements have been found.\n\
Please check if your order of Alpha_s and Alpha_ew have the right value.\n"
<< Exception::runerror;
// check if we have virtual contributions
bool haveVirtuals = true;
// check DR conventions of virtual contributions
bool virtualsAreDR = false;
bool virtualsAreCDR = false;
// check finite term conventions of virtual contributions
bool virtualsAreCS = false;
bool virtualsAreBDK = false;
bool virtualsAreExpanded = false;
// renormalization scheme
bool virtualsAreDRbar = false;
// check and prepare the Born and virtual matrix elements
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator born
= bornMEs().begin(); born != bornMEs().end(); ++born ) {
prepareME(*born);
haveVirtuals &= (**born).haveOneLoop();
if ( needTrueVirtuals ) {
if ( (**born).haveOneLoop() ) {
virtualsAreDRbar |= (**born).isDRbar();
virtualsAreDR |= (**born).isDR();
virtualsAreCDR |= !(**born).isDR();
virtualsAreCS |= (**born).isCS();
virtualsAreBDK |= (**born).isBDK();
virtualsAreExpanded |= (**born).isExpanded();
}
}
}
// prepare the loop induced matrix elements
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator looped
= loopInducedMEs().begin(); looped != loopInducedMEs().end(); ++looped ) {
prepareME(*looped);
}
if ( needTrueVirtuals ) {
// check the additional insertion operators
if ( !virtuals().empty() )
haveVirtuals = true;
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= virtuals().begin(); virt != virtuals().end(); ++virt ) {
virtualsAreDRbar |= (**virt).isDRbar();
virtualsAreDR |= (**virt).isDR();
virtualsAreCDR |= !(**virt).isDR();
virtualsAreCS |= (**virt).isCS();
virtualsAreBDK |= (**virt).isBDK();
virtualsAreExpanded |= (**virt).isExpanded();
}
// check for consistent conventions on virtuals, if we are to include them
if ( virtualContributions() ) {
if ( !haveVirtuals ) {
throw Exception() << "MatchboxFactory: Could not find amplitudes for all virtual contributions needed.\n"
<< Exception::runerror;
}
if ( virtualsAreDR && virtualsAreCDR ) {
throw Exception() << "MatchboxFactory: Virtual corrections use inconsistent regularization schemes.\n"
<< Exception::runerror;
}
if ( (virtualsAreCS && virtualsAreBDK) ||
(virtualsAreCS && virtualsAreExpanded) ||
(virtualsAreBDK && virtualsAreExpanded) ||
(!virtualsAreCS && !virtualsAreBDK && !virtualsAreExpanded) ) {
throw Exception() << "MatchboxFactory: Virtual corrections use inconsistent conventions on finite terms.\n"
<< Exception::runerror;
}
}
}
// prepare the real emission matrix elements
if ( realContributions() || meCorrectionsOnly() ||
(showerApproximation() && virtualContributions()) ||
(showerApproximation() && loopSimCorrections()) ) {
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator real
= realEmissionMEs().begin(); real != realEmissionMEs().end(); ++real ) {
prepareME(*real);
}
}
// start creating matrix elements
MEs().clear();
// setup born and virtual contributions
if ( bornContributions() || virtualContributions() ) {
generator()->log() << "preparing Born"
<< (virtualContributions() ? " and virtual" : "")
<< " matrix elements.\n" << flush;
}
if ( (bornContributions() && !virtualContributions()) ||
(bornContributions() && meCorrectionsOnly()) ||
(bornContributions() && virtualContributions() && independentVirtuals()) ) {
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator born
= bornMEs().begin(); born != bornMEs().end(); ++born ) {
if ( (**born).onlyOneLoop() )
continue;
Ptr<MatchboxMEBase>::ptr bornme = (**born).cloneMe();
string pname = fullName() + "/" + (**born).name();
if ( virtualContributions() && independentVirtuals() )
pname += ".Born";
if ( ! (generator()->preinitRegister(bornme,pname) ) )
throw Exception() << "MatchboxFactory: Matrix element " << pname << " already existing."
<< Exception::runerror;
if ( bornme->isOLPTree() ) {
int id = orderOLPProcess(bornme->subProcess(),
(**born).matchboxAmplitude(),
ProcessType::treeME2);
bornme->olpProcess(ProcessType::treeME2,id);
}
bornme->needsNoCorrelations();
bornme->cloneDependencies();
MEs().push_back(bornme);
}
}
if ( bornContributions() && !loopInducedMEs().empty() ) {
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator looped
= loopInducedMEs().begin(); looped != loopInducedMEs().end(); ++looped ) {
Ptr<MatchboxMEBase>::ptr loopme = (**looped).cloneMe();
string pname = fullName() + "/" + (**looped).name() + ".LoopInduced";
if ( ! (generator()->preinitRegister(loopme,pname) ) )
throw Exception() << "MatchboxFactory: Matrix element " << pname << " already existing."
<< Exception::runerror;
if ( loopme->isOLPTree() ) {
int id = orderOLPProcess(loopme->subProcess(),
(**looped).matchboxAmplitude(),
ProcessType::loopInducedME2);
loopme->olpProcess(ProcessType::loopInducedME2,id);
}
loopme->needsNoCorrelations();
loopme->cloneDependencies();
MEs().push_back(loopme);
}
}
if ( needTrueVirtuals ) {
bornVirtualMEs().clear();
progress_display progressBar{ bornMEs().size(), generator()->log() };
if ( thePoleData != "" )
if ( thePoleData[thePoleData.size()-1] != '/' )
thePoleData += "/";
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator born
= bornMEs().begin(); born != bornMEs().end(); ++born ) {
Ptr<MatchboxMEBase>::ptr nlo = (**born).cloneMe();
string pname = fullName() + "/" + (**born).name();
if ( !independentVirtuals() && !(!bornContributions() && virtualContributions()) )
pname += ".BornVirtual";
else if ( independentPKs() && !nlo->onlyOneLoop() )
pname += ".VirtualVI";
else
pname += ".Virtual";
if ( ! (generator()->preinitRegister(nlo,pname) ) )
throw Exception() << "MatchboxFactory: NLO ME " << pname << " already existing."
<< Exception::runerror;
nlo->virtuals().clear();
if ( !nlo->onlyOneLoop() ) {
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= virtuals().begin(); virt != virtuals().end(); ++virt ) {
if ( (**virt).apply((**born).diagrams().front()->partons()) )
nlo->virtuals().push_back(*virt);
}
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= DipoleRepository::insertionIOperators(dipoleSet()).begin();
virt != DipoleRepository::insertionIOperators(dipoleSet()).end(); ++virt ) {
if ( (**virt).apply((**born).diagrams().front()->partons()) )
nlo->virtuals().push_back(*virt);
}
if ( !independentVirtuals() || ( independentVirtuals() && !independentPKs() ) ) {
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= DipoleRepository::insertionPKOperators(dipoleSet()).begin();
virt != DipoleRepository::insertionPKOperators(dipoleSet()).end(); ++virt ) {
if ( (**virt).apply((**born).diagrams().front()->partons()) )
nlo->virtuals().push_back(*virt);
}
}
if ( nlo->virtuals().empty() )
throw Exception() << "MatchboxFactory: No insertion operators have been found for "
<< (**born).name() << "\n"
<< Exception::runerror;
if ( checkPoles() ) {
if ( !virtualsAreExpanded ) {
throw Exception()
<< "MatchboxFactory: Cannot check epsilon poles if virtuals are not in `expanded' convention.\n"
<< Exception::runerror;
}
}
}
if ( !bornContributions() || independentVirtuals() ) {
nlo->doOneLoopNoBorn();
} else {
nlo->doOneLoop();
}
if ( nlo->isOLPLoop() ) {
int id = orderOLPProcess(nlo->subProcess(),
(**born).matchboxAmplitude(),
ProcessType::oneLoopInterference);
nlo->olpProcess(ProcessType::oneLoopInterference,id);
if ( !nlo->onlyOneLoop() && nlo->needsOLPCorrelators() ) {
id = orderOLPProcess(nlo->subProcess(),
(**born).matchboxAmplitude(),
ProcessType::colourCorrelatedME2);
nlo->olpProcess(ProcessType::colourCorrelatedME2,id);
}
}
nlo->needsCorrelations();
nlo->cloneDependencies();
bornVirtualMEs().push_back(nlo);
MEs().push_back(nlo);
if ( independentVirtuals() && independentPKs() && !nlo->onlyOneLoop() ) {
Ptr<MatchboxMEBase>::ptr nlopk = (**born).cloneMe();
string pnamepk = fullName() + "/" + (**born).name();
pnamepk += ".VirtualPK";
if ( ! (generator()->preinitRegister(nlopk,pnamepk) ) )
throw Exception() << "MatchboxFactory: NLO ME " << pnamepk << " already existing."
<< Exception::runerror;
nlopk->virtuals().clear();
for ( vector<Ptr<MatchboxInsertionOperator>::ptr>::const_iterator virt
= DipoleRepository::insertionPKOperators(dipoleSet()).begin();
virt != DipoleRepository::insertionPKOperators(dipoleSet()).end(); ++virt ) {
if ( (**virt).apply((**born).diagrams().front()->partons()) )
nlopk->virtuals().push_back(*virt);
}
if ( !nlopk->virtuals().empty() ) {
nlopk->doOneLoopNoBorn();
nlopk->doOneLoopNoLoops();
if ( nlopk->isOLPLoop() ) {
int id = orderOLPProcess(nlopk->subProcess(),
(**born).matchboxAmplitude(),
ProcessType::treeME2);
nlopk->olpProcess(ProcessType::treeME2,id);
if ( nlopk->needsOLPCorrelators() ) {
id = orderOLPProcess(nlopk->subProcess(),
(**born).matchboxAmplitude(),
ProcessType::colourCorrelatedME2);
nlopk->olpProcess(ProcessType::colourCorrelatedME2,id);
}
}
nlopk->needsCorrelations();
nlopk->cloneDependencies();
bornVirtualMEs().push_back(nlopk);
MEs().push_back(nlopk);
}
}
++progressBar;
}
generator()->log() << "---------------------------------------------------\n"
<< flush;
}
theSplittingDipoles.clear();
set<cPDVector> bornProcs;
if ( showerApproximation() ) {
if ( showerApproximation()->needsSplittingGenerator() ) {
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator born
= bornMEs().begin(); born != bornMEs().end(); ++born )
for ( MEBase::DiagramVector::const_iterator d = (**born).diagrams().begin();
d != (**born).diagrams().end(); ++d )
bornProcs.insert((**d).partons());
}
}
if ( realContributions() || meCorrectionsOnly() ||
(showerApproximation() && virtualContributions()) ||
(showerApproximation() && loopSimCorrections()) ) {
generator()->log() << "preparing subtracted matrix elements.\n" << flush;
if ( theSubtractionData != "" )
if ( theSubtractionData[theSubtractionData.size()-1] != '/' )
theSubtractionData += "/";
subtractedMEs().clear();
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator born
= bornMEs().begin(); born != bornMEs().end(); ++born ) {
if ( (**born).onlyOneLoop() )
continue;
(**born).needsCorrelations();
if ( (**born).isOLPTree() ) {
int id = orderOLPProcess((**born).subProcess(),
(**born).matchboxAmplitude(),
ProcessType::colourCorrelatedME2);
(**born).olpProcess(ProcessType::colourCorrelatedME2,id);
bool haveGluon = false;
for ( PDVector::const_iterator p = (**born).subProcess().legs.begin();
p != (**born).subProcess().legs.end(); ++p )
if ( (**p).id() == 21 ) {
haveGluon = true;
break;
}
if ( haveGluon ) {
id = orderOLPProcess((**born).subProcess(),
(**born).matchboxAmplitude(),
ProcessType::spinColourCorrelatedME2);
(**born).olpProcess(ProcessType::spinColourCorrelatedME2,id);
}
if ( showerApproximation() ) {
id = orderOLPProcess((**born).subProcess(),
(**born).matchboxAmplitude(),
ProcessType::treeME2);
(**born).olpProcess(ProcessType::treeME2,id);
}
}
}
progress_display progressBar{ realEmissionMEs().size(), generator()->log() };
for ( vector<Ptr<MatchboxMEBase>::ptr>::iterator real
= realEmissionMEs().begin(); real != realEmissionMEs().end(); ++real ) {
Ptr<SubtractedME>::ptr sub = new_ptr(SubtractedME());
string pname = fullName() + "/" + (**real).name() + ".SubtractedReal";
if ( ! (generator()->preinitRegister(sub,pname) ) )
throw Exception() << "MatchboxFactory: Subtracted ME " << pname << " already existing."
<< Exception::runerror;
(**real).needsNoCorrelations();
if ( (**real).isOLPTree() ) {
int id = orderOLPProcess((**real).subProcess(),
(**real).matchboxAmplitude(),
ProcessType::treeME2);
(**real).olpProcess(ProcessType::treeME2,id);
}
sub->head(*real);
sub->dependent().clear();
sub->getDipoles();
if ( sub->dependent().empty() ) {
// finite real contribution
if ( realContributions() ) {
Ptr<MatchboxMEBase>::ptr fme =
dynamic_ptr_cast<Ptr<MatchboxMEBase>::ptr>(sub->head())->cloneMe();
string qname = fullName() + "/" + (**real).name() + ".FiniteReal";
if ( ! (generator()->preinitRegister(fme,qname) ) )
throw Exception() << "MatchboxFactory: ME " << qname << " already existing."
<< Exception::runerror;
MEs().push_back(fme);
finiteRealMEs().push_back(fme);
}
sub->head(tMEPtr());
++progressBar;
continue;
}
if ( realEmissionScales() )
sub->doRealEmissionScales();
subtractedMEs().push_back(sub);
if ( realContributions() )
if ( !showerApproximation() || (showerApproximation() && showerApproximation()->hasHEvents()) )
MEs().push_back(sub);
if ( showerApproximation() ) {
if ( virtualContributions() && !meCorrectionsOnly() && !loopSimCorrections() ) {
Ptr<SubtractedME>::ptr subv = new_ptr(*sub);
string vname = sub->fullName() + ".SubtractionIntegral";
if ( ! (generator()->preinitRegister(subv,vname) ) )
throw Exception() << "MatchboxFactory: Subtracted ME " << vname << " already existing."
<< Exception::runerror;
subv->cloneDependencies(vname);
subv->doVirtualShowerSubtraction();
subtractedMEs().push_back(subv);
MEs().push_back(subv);
}
if ( loopSimCorrections() ) {
Ptr<SubtractedME>::ptr subv = new_ptr(*sub);
string vname = sub->fullName() + ".SubtractionIntegral";
if ( ! (generator()->preinitRegister(subv,vname) ) )
throw Exception() << "MatchboxFactory: Subtracted ME " << vname << " already existing."
<< Exception::runerror;
subv->cloneDependencies(vname);
subv->doLoopSimSubtraction();
subtractedMEs().push_back(subv);
MEs().push_back(subv);
}
sub->doRealShowerSubtraction();
if ( showerApproximation()->needsSplittingGenerator() )
for ( set<cPDVector>::const_iterator p = bornProcs.begin();
p != bornProcs.end(); ++p ) {
vector<Ptr<SubtractionDipole>::ptr> sdip = sub->splitDipoles(*p);
set<Ptr<SubtractionDipole>::ptr>& dips = theSplittingDipoles[*p];
copy(sdip.begin(),sdip.end(),inserter(dips,dips.begin()));
}
}
++progressBar;
}
generator()->log() << "---------------------------------------------------\n"
<< flush;
}
if ( !theSplittingDipoles.empty() ) {
map<Ptr<SubtractionDipole>::ptr,Ptr<SubtractionDipole>::ptr> cloneMap;
for ( map<cPDVector,set<Ptr<SubtractionDipole>::ptr> >::const_iterator sd = theSplittingDipoles.begin();
sd != theSplittingDipoles.end(); ++sd ) {
for ( set<Ptr<SubtractionDipole>::ptr>::const_iterator d = sd->second.begin();
d != sd->second.end(); ++d ) {
cloneMap[*d] = Ptr<SubtractionDipole>::ptr();
}
}
for ( map<Ptr<SubtractionDipole>::ptr,Ptr<SubtractionDipole>::ptr>::iterator cd =
cloneMap.begin(); cd != cloneMap.end(); ++cd ) {
Ptr<SubtractionDipole>::ptr cloned = cd->first->cloneMe();
string dname = cd->first->fullName() + ".splitting";
if ( ! (generator()->preinitRegister(cloned,dname)) )
throw Exception() << "MatchboxFactory: Dipole '" << dname << "' already existing."
<< Exception::runerror;
cloned->cloneDependencies();
cloned->showerApproximation(Ptr<ShowerApproximation>::tptr());
cloned->doSplitting();
cd->second = cloned;
}
for ( map<cPDVector,set<Ptr<SubtractionDipole>::ptr> >::iterator sd = theSplittingDipoles.begin();
sd != theSplittingDipoles.end(); ++sd ) {
set<Ptr<SubtractionDipole>::ptr> cloned;
for ( set<Ptr<SubtractionDipole>::ptr>::iterator d = sd->second.begin();
d != sd->second.end(); ++d ) {
cloned.insert(cloneMap[*d]);
}
sd->second = cloned;
}
}
if ( !externalAmplitudes().empty() ) {
generator()->log() << "Initializing external amplitudes.\n" << flush;
for ( set<Ptr<MatchboxAmplitude>::tptr>::const_iterator ext =
externalAmplitudes().begin(); ext != externalAmplitudes().end(); ++ext ) {
if ( !(**ext).initializeExternal() ) {
throw Exception() << "Failed to initialize amplitude '" << (**ext).name() << "'\n"
<< Exception::runerror;
}
}
generator()->log() << "---------------------------------------------------\n"
<< flush;
}
if ( !olpProcesses().empty() ) {
generator()->log() << "Initializing one-loop provider(s).\n" << flush;
map<Ptr<MatchboxAmplitude>::tptr,map<pair<Process,int>,int> > olps;
for ( map<Ptr<MatchboxAmplitude>::tptr,map<pair<Process,int>,int> >::const_iterator
oit = olpProcesses().begin(); oit != olpProcesses().end(); ++oit ) {
olps[oit->first] = oit->second;
}
for ( map<Ptr<MatchboxAmplitude>::tptr,map<pair<Process,int>,int> >::const_iterator
olpit = olps.begin(); olpit != olps.end(); ++olpit ) {
if ( !olpit->first->startOLP(olpit->second) ) {
throw Exception() << "MatchboxFactory: Failed to start OLP for amplitude '" << olpit->first->name() << "'\n"
<< Exception::runerror;
}
}
generator()->log() << "---------------------------------------------------\n"
<< flush;
}
generator()->log() << "Process setup finished.\n" << flush;
ranSetup = true;
}
}
void MatchboxFactory::SplittingChannel::print(ostream& os) const {
os << "--- SplittingChannel setup -----------------------------------------------------\n";
os << " Born process ";
const StandardXComb& bxc = *bornXComb;
os << bxc.mePartonData()[0]->PDGName() << " "
<< bxc.mePartonData()[1]->PDGName() << " -> ";
for ( cPDVector::const_iterator p = bxc.mePartonData().begin() + 2;
p != bxc.mePartonData().end(); ++p ) {
os << (**p).PDGName() << " ";
}
os << "\n";
os << " to real emission process ";
const StandardXComb& rxc = *realXComb;
os << rxc.mePartonData()[0]->PDGName() << " "
<< rxc.mePartonData()[1]->PDGName() << " -> ";
for ( cPDVector::const_iterator p = rxc.mePartonData().begin() + 2;
p != rxc.mePartonData().end(); ++p ) {
os << (**p).PDGName() << " ";
}
os << "\n";
os << " with dipole:\n";
dipole->print(os);
os << "---------------------------------------------------\n";
os << flush;
}
list<MatchboxFactory::SplittingChannel>
MatchboxFactory::getSplittingChannels(tStdXCombPtr xcptr) const {
if ( xcptr->lastProjector() )
xcptr = xcptr->lastProjector();
const StandardXComb& xc = *xcptr;
cPDVector proc = xc.mePartonData();
map<cPDVector,set<Ptr<SubtractionDipole>::ptr> >::const_iterator splitEntries
= splittingDipoles().find(proc);
list<SplittingChannel> res;
if ( splitEntries == splittingDipoles().end() )
return res;
const set<Ptr<SubtractionDipole>::ptr>& splitDipoles = splitEntries->second;
SplittingChannel channel;
if ( !splitDipoles.empty() ) {
Ptr<MatchboxMEBase>::tptr bornME =
const_ptr_cast<Ptr<MatchboxMEBase>::tptr>((**splitDipoles.begin()).underlyingBornME());
channel.bornXComb =
bornME->makeXComb(xc.maxEnergy(),xc.particles(),xc.eventHandlerPtr(),
const_ptr_cast<tSubHdlPtr>(xc.subProcessHandler()),
xc.pExtractor(),xc.CKKWHandler(),
xc.partonBins(),xc.cuts(),xc.diagrams(),xc.mirror(),
PartonPairVec());
}
for ( set<Ptr<SubtractionDipole>::ptr>::const_iterator sd =
splitDipoles.begin(); sd != splitDipoles.end(); ++sd ) {
channel.dipole = *sd;
vector<StdXCombPtr> realXCombs = (**sd).makeRealXCombs(channel.bornXComb);
for ( vector<StdXCombPtr>::const_iterator rxc = realXCombs.begin();
rxc != realXCombs.end(); ++rxc ) {
channel.realXComb = *rxc;
if ( showerApproximation()->needsTildeXCombs() ) {
channel.tildeXCombs.clear();
assert(!channel.dipole->partnerDipoles().empty());
for ( vector<Ptr<SubtractionDipole>::tptr>::const_iterator p =
channel.dipole->partnerDipoles().begin();
p != channel.dipole->partnerDipoles().end(); ++p ) {
StdXCombPtr txc = channel.dipole->makeBornXComb(channel.realXComb);
if ( txc )
channel.tildeXCombs.push_back(txc);
}
}
res.push_back(channel);
}
}
if ( initVerbose() ) {
generator()->log()
<< "--- MatchboxFactory splitting channels ----------------------------------------------\n";
const StandardXComb& bxc = *xcptr;
generator()->log() << " hard process handled is: ";
generator()->log() << bxc.mePartonData()[0]->PDGName() << " "
<< bxc.mePartonData()[1]->PDGName() << " -> ";
for ( cPDVector::const_iterator p = bxc.mePartonData().begin() + 2;
p != bxc.mePartonData().end(); ++p ) {
generator()->log() << (**p).PDGName() << " ";
}
generator()->log() << "\n";
for ( list<MatchboxFactory::SplittingChannel>::const_iterator sp =
res.begin(); sp != res.end(); ++sp ) {
sp->print(generator()->log());
}
generator()->log()
<< "--------------------------------------------------------\n"
<< flush;
}
return res;
}
void MatchboxFactory::print(ostream& os) const {
os << "--- MatchboxFactory setup -----------------------------------------------------------\n";
if ( !amplitudes().empty() ) {
os << " generated Born matrix elements:\n";
for ( vector<Ptr<MatchboxMEBase>::ptr>::const_iterator m = bornMEs().begin();
m != bornMEs().end(); ++m ) {
(**m).print(os);
}
os << flush;
os << " generated real emission matrix elements:\n";
for ( vector<Ptr<MatchboxMEBase>::ptr>::const_iterator m = realEmissionMEs().begin();
m != realEmissionMEs().end(); ++m ) {
(**m).print(os);
}
os << flush;
}
os << " generated Born+virtual matrix elements:\n";
for ( vector<Ptr<MatchboxMEBase>::ptr>::const_iterator bv
= bornVirtualMEs().begin(); bv != bornVirtualMEs().end(); ++bv ) {
(**bv).print(os);
}
os << " generated subtracted matrix elements:\n";
for ( vector<Ptr<SubtractedME>::ptr>::const_iterator sub
= subtractedMEs().begin(); sub != subtractedMEs().end(); ++sub ) {
os << " '" << (**sub).name() << "'\n";
}
os << "---------------------------------------------------\n";
os << flush;
}
void MatchboxFactory::summary(ostream& os) const {
os << "\n\n================================================================================\n"
<< " Matchbox hard process summary\n"
<< "================================================================================\n\n";
os << " Electro-weak parameter summary:\n"
<< "---------------------------------------------------\n\n";
os << " Electro-weak scheme : ";
switch ( SM().ewScheme() ) {
case 0: os << "Default"; break;
case 1: os << "GMuScheme"; break;
case 2: os << "alphaMZScheme"; break;
case 3: os << "NoMass"; break;
case 4: os << "mW"; break;
case 5: os << "mZ"; break;
case 6: os << "Independent"; break;
case 7: os << "FeynRulesUFO"; break;
default: assert(false);
}
os << "\n";
os << " alphaEM is "
<< (SM().ewScheme() == 0 && !theFixedQEDCouplings ? "running" : "fixed at alphaEM(m(Z))") << "\n";
if ( SM().ewScheme() == 0 && !theFixedQEDCouplings )
os << " alphaEM is running at " << SM().alphaEMPtr()->nloops()
<< " loops\n\n";
else
os << "\n";
os << (SM().ewScheme() != 0 ? " Tree level relations " : " Best values ")
<< "yield:\n\n"
<< " m(Z)/GeV = "
<< getParticleData(ParticleID::Z0)->hardProcessMass()/GeV
<< "\n"
<< " g(Z)/GeV = "
<< getParticleData(ParticleID::Z0)->hardProcessWidth()/GeV
<< "\n"
<< " m(W)/GeV = "
<< getParticleData(ParticleID::Wplus)->hardProcessMass()/GeV
<< "\n"
<< " g(W)/GeV = "
<< getParticleData(ParticleID::Wplus)->hardProcessWidth()/GeV
<< "\n"
<< " m(H)/GeV = "
<< getParticleData(ParticleID::h0)->hardProcessMass()/GeV
<< "\n"
<< " g(H)/GeV = "
<< getParticleData(ParticleID::h0)->hardProcessWidth()/GeV
<< "\n"
<< " alphaEM(m(Z)) = "
<< SM().alphaEMME(sqr(getParticleData(ParticleID::Z0)->hardProcessMass())) << "\n"
<< " sin^2(theta) = " << SM().sin2ThetaW()
<< "\n"
<< " GeV^2 GF = " << GeV2*SM().fermiConstant()
<< "\n\n";
os << " Quark masses and widths are:\n"
<< "---------------------------------------------------\n\n"
<< " m(u)/GeV = " << getParticleData(ParticleID::u)->hardProcessMass()/GeV << "\n"
<< " m(d)/GeV = " << getParticleData(ParticleID::d)->hardProcessMass()/GeV << "\n"
<< " m(c)/GeV = " << getParticleData(ParticleID::c)->hardProcessMass()/GeV << "\n"
<< " m(s)/GeV = " << getParticleData(ParticleID::s)->hardProcessMass()/GeV << "\n"
<< " m(t)/GeV = " << getParticleData(ParticleID::t)->hardProcessMass()/GeV << "\n"
<< " g(t)/GeV = " << getParticleData(ParticleID::t)->hardProcessWidth()/GeV << "\n"
<< " m(b)/GeV = " << getParticleData(ParticleID::b)->hardProcessMass()/GeV << "\n\n";
os << " Lepton masses and widths are:\n"
<< "---------------------------------------------------\n\n"
<< " m(n_e)/GeV = " << getParticleData(ParticleID::nu_e)->hardProcessMass()/GeV << "\n"
<< " m(e)/GeV = " << getParticleData(ParticleID::eminus)->hardProcessMass()/GeV << "\n"
<< " m(n_mu)/GeV = " << getParticleData(ParticleID::nu_mu)->hardProcessMass()/GeV << "\n"
<< " m(mu)/GeV = " << getParticleData(ParticleID::muminus)->hardProcessMass()/GeV << "\n"
<< " m(nu_tau)/GeV = " << getParticleData(ParticleID::nu_tau)->hardProcessMass()/GeV << "\n"
<< " m(tau)/GeV = " << getParticleData(ParticleID::tauminus)->hardProcessMass()/GeV << "\n\n";
os << " Strong coupling summary:\n"
<< "---------------------------------------------------\n\n";
os << " alphaS is";
if ( !theFixedCouplings ) {
os << " running at " << SM().alphaSPtr()->nloops()
<< " loops with\n"
<< " alphaS(m(Z)) = " << SM().alphaSPtr()->value(sqr(getParticleData(ParticleID::Z0)->mass()))
<< "\n\n";
} else {
os << " fixed at "
<< SM().alphaS()
<< "\n\n";
}
if ( !theFixedCouplings ) {
os << " flavour thresholds are matched at\n";
for ( long id = 1; id <= 6; ++id ) {
os << " m(" << id << ")/GeV = "
<< (SM().alphaSPtr()->quarkMasses().empty() ?
getParticleData(id)->mass()/GeV :
SM().alphaSPtr()->quarkMasses()[id-1]/GeV)
<< "\n";
}
}
os << "\n\n" << flush;
}
void MatchboxFactory::doinit() {
theIsMatchboxRun() = true;
theCurrentFactory = Ptr<MatchboxFactory>::tptr(this);
if ( RunDirectories::empty() )
RunDirectories::pushRunId(generator()->runName());
setup();
if ( theShowerApproximation )
theShowerApproximation->init();
if ( initVerbose() && !ranSetup )
print(Repository::clog());
Ptr<StandardEventHandler>::tptr eh =
dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(generator()->eventHandler());
assert(eh);
if ( initVerbose() && !ranSetup ) {
assert(standardModel());
standardModel()->init();
summary(Repository::clog());
}
SubProcessHandler::doinit();
}
void MatchboxFactory::doinitrun() {
theIsMatchboxRun() = true;
theCurrentFactory = Ptr<MatchboxFactory>::tptr(this);
if ( theShowerApproximation )
theShowerApproximation->initrun();
Ptr<StandardEventHandler>::tptr eh =
dynamic_ptr_cast<Ptr<StandardEventHandler>::tptr>(generator()->eventHandler());
assert(eh);
SubProcessHandler::doinitrun();
}
const string& MatchboxFactory::buildStorage() {
return RunDirectories::buildStorage();
}
const string& MatchboxFactory::runStorage() {
return RunDirectories::runStorage();
}
void MatchboxFactory::persistentOutput(PersistentOStream & os) const {
os << theDiagramGenerator << theProcessData
<< theNLight
<< theNLightJetVec << theNHeavyJetVec << theNLightProtonVec
<< theOrderInAlphaS << theOrderInAlphaEW
<< theBornContributions << theVirtualContributions
<< theRealContributions << theIndependentVirtuals << theIndependentPKs
<< thePhasespace << theScaleChoice
<< theFactorizationScaleFactor << theRenormalizationScaleFactor
<< theFixedCouplings << theFixedQEDCouplings << theVetoScales
<< theAmplitudes
<< theBornMEs << theVirtuals << theRealEmissionMEs << theLoopInducedMEs
<< theBornVirtualMEs << theSubtractedMEs << theFiniteRealMEs
<< theVerbose << theInitVerbose << theSubtractionData << theSubtractionPlotType
<< theSubtractionScatterPlot << thePoleData
<< theParticleGroups << processes << loopInducedProcesses << realEmissionProcesses
<< theShowerApproximation << theSplittingDipoles
<< theRealEmissionScales << theAllProcesses
<< theOLPProcesses << theExternalAmplitudes
<< theSelectedAmplitudes << theDeselectedAmplitudes
<< theDipoleSet << theReweighters << thePreweighters
<< theMECorrectionsOnly<< theLoopSimCorrections<<theHighestVirtualsize << ranSetup
<< theIncoming << theFirstPerturbativePDF << theSecondPerturbativePDF
<< inProductionMode << theSpinCorrelations << theAlphaParameter
<< theEnforceChargeConservation << theEnforceColourConservation
<< theEnforceLeptonNumberConservation << theEnforceQuarkNumberConservation
<< theLeptonFlavourDiagonal << theQuarkFlavourDiagonal;
}
void MatchboxFactory::persistentInput(PersistentIStream & is, int) {
is >> theDiagramGenerator >> theProcessData
>> theNLight
>> theNLightJetVec >> theNHeavyJetVec >> theNLightProtonVec
>> theOrderInAlphaS >> theOrderInAlphaEW
>> theBornContributions >> theVirtualContributions
>> theRealContributions >> theIndependentVirtuals >> theIndependentPKs
>> thePhasespace >> theScaleChoice
>> theFactorizationScaleFactor >> theRenormalizationScaleFactor
>> theFixedCouplings >> theFixedQEDCouplings >> theVetoScales
>> theAmplitudes
>> theBornMEs >> theVirtuals >> theRealEmissionMEs >> theLoopInducedMEs
>> theBornVirtualMEs >> theSubtractedMEs >> theFiniteRealMEs
>> theVerbose >> theInitVerbose >> theSubtractionData >> theSubtractionPlotType
>> theSubtractionScatterPlot >> thePoleData
>> theParticleGroups >> processes >> loopInducedProcesses >> realEmissionProcesses
>> theShowerApproximation >> theSplittingDipoles
>> theRealEmissionScales >> theAllProcesses
>> theOLPProcesses >> theExternalAmplitudes
>> theSelectedAmplitudes >> theDeselectedAmplitudes
>> theDipoleSet >> theReweighters >> thePreweighters
>> theMECorrectionsOnly>> theLoopSimCorrections>>theHighestVirtualsize >> ranSetup
>> theIncoming >> theFirstPerturbativePDF >> theSecondPerturbativePDF
>> inProductionMode >> theSpinCorrelations >> theAlphaParameter
>> theEnforceChargeConservation >> theEnforceColourConservation
>> theEnforceLeptonNumberConservation >> theEnforceQuarkNumberConservation
>> theLeptonFlavourDiagonal >> theQuarkFlavourDiagonal;
}
string MatchboxFactory::startParticleGroup(string name) {
particleGroupName = StringUtils::stripws(name);
particleGroup.clear();
return "";
}
string MatchboxFactory::endParticleGroup(string) {
if ( particleGroup.empty() )
throw Exception() << "MatchboxFactory: Empty particle group."
<< Exception::runerror;
particleGroups()[particleGroupName] = particleGroup;
particleGroup.clear();
return "";
}
vector<string> MatchboxFactory::parseProcess(string in) {
vector<string> process = StringUtils::split(in);
if ( process.size() < 3 )
throw Exception() << "MatchboxFactory: Invalid process."
<< Exception::runerror;
for ( vector<string>::iterator p = process.begin();
p != process.end(); ++p ) {
*p = StringUtils::stripws(*p);
}
vector<string> pprocess;
for ( vector<string>::const_iterator p = process.begin();
p != process.end(); ++p ) {
if ( *p == "->" )
continue;
pprocess.push_back(*p);
}
return pprocess;
}
string MatchboxFactory::doProcess(string in) {
processes.push_back(parseProcess(in));
return "";
}
string MatchboxFactory::doLoopInducedProcess(string in) {
loopInducedProcesses.push_back(parseProcess(in));
return "";
}
string MatchboxFactory::doSingleRealProcess(string in) {
realEmissionProcesses.push_back(parseProcess(in));
return "";
}
struct SortPID {
inline bool operator()(PDPtr a, PDPtr b) const {
return a->id() < b->id();
}
};
//
// @TODO
//
// SP: After improving this for standard model process building this should
// actually got into a separate process builder class or something along these
// lines to have it better factored for use with BSM models.
//
//
set<PDVector> MatchboxFactory::
makeSubProcesses(const vector<string>& proc) const {
if ( proc.empty() )
throw Exception() << "MatchboxFactory: No process specified."
<< Exception::runerror;
vector<PDVector> groups;
typedef map<string,PDVector>::const_iterator GroupIterator;
for ( vector<string>::const_iterator gr = proc.begin();
gr != proc.end(); ++gr ) {
GroupIterator git = particleGroups().find(*gr);
if ( git == particleGroups().end() ) {
throw Exception() << "MatchboxFactory: Particle group '"
<< *gr << "' not defined." << Exception::runerror;
}
groups.push_back(git->second);
}
vector<size_t> counts(groups.size(),0);
PDVector proto(groups.size());
set<PDVector> allProcs;
while ( true ) {
for ( size_t k = 0; k < groups.size(); ++k )
proto[k] = groups[k][counts[k]];
int charge = 0;
int colour = 0;
int nleptons = 0;
int nquarks = 0;
int ncolour = 0;
int nleptonsGen[4];
int nquarksGen[4];
for ( size_t i = 0; i < 4; ++i ) {
nleptonsGen[i] = 0;
nquarksGen[i] = 0;
}
for ( size_t k = 0; k < proto.size(); ++k ) {
int sign = k > 1 ? 1 : -1;
charge += sign * proto[k]->iCharge();
colour += sign * proto[k]->iColour();
if ( abs(proto[k]->id()) <= 8 ) {
int generation = (abs(proto[k]->id()) - 1)/2;
nquarks += sign * ( proto[k]->id() < 0 ? -1 : 1);
nquarksGen[generation] += sign * ( proto[k]->id() < 0 ? -1 : 1);
}
if ( abs(proto[k]->id()) > 10 &&
abs(proto[k]->id()) <= 18 ) {
int generation = (abs(proto[k]->id()) - 11)/2;
nleptons += sign * ( proto[k]->id() < 0 ? -1 : 1);
nleptonsGen[generation] += sign * ( proto[k]->id() < 0 ? -1 : 1);
}
if ( proto[k]->coloured() )
++ncolour;
}
bool pass = true;
if ( theEnforceChargeConservation )
pass &= (charge == 0);
if ( theEnforceColourConservation )
pass &= (colour % 8 == 0);
if ( theEnforceLeptonNumberConservation ) {
pass &= (nleptons == 0);
if ( theLeptonFlavourDiagonal ) {
for ( size_t i = 0; i < 4; ++i )
pass &= (nleptonsGen[i] == 0);
}
}
if ( theEnforceQuarkNumberConservation ) {
pass &= (nquarks == 0);
if ( theQuarkFlavourDiagonal ) {
for ( size_t i = 0; i < 4; ++i )
pass &= (nquarksGen[i] == 0);
}
}
if ( pass ) {
for ( int i = 0; i < 2; ++i ) {
if ( proto[i]->coloured() &&
proto[i]->hardProcessMass() != ZERO )
throw Exception()
<< "Inconsistent flavour scheme detected with massive incoming "
<< proto[i]->PDGName() << ". Check your setup."
<< Exception::runerror;
}
sort(proto.begin()+2,proto.end(),SortPID());
allProcs.insert(proto);
}
vector<size_t>::reverse_iterator c = counts.rbegin();
vector<PDVector>::const_reverse_iterator g = groups.rbegin();
while ( c != counts.rend() ) {
if ( ++(*c) == g->size() ) {
*c = 0;
++c; ++g;
} else {
break;
}
}
if ( c == counts.rend() )
break;
}
return allProcs;
}
void MatchboxFactory::Init() {
static ClassDocumentation<MatchboxFactory> documentation
("MatchboxFactory",
"NLO QCD corrections have been calculated "
"using Matchbox \\cite{Platzer:2011bc}, \\cite{Matchbox:2015}",
"%\\cite{Platzer:2011bc}\n"
"\\bibitem{Platzer:2011bc}\n"
"S.~Platzer and S.~Gieseke,\n"
"``Dipole Showers and Automated NLO Matching in Herwig,''\n"
"arXiv:1109.6256 [hep-ph].\n"
"%%CITATION = ARXIV:1109.6256;%%\n"
"%\\cite{Matchbox:2015}\n"
"\\bibitem{Matchbox:2015}\n"
"Herwig collaboration,\n"
"``Precision LHC Event Generation with Herwig,''\n"
"in preparation.");
static Reference<MatchboxFactory,Tree2toNGenerator> interfaceDiagramGenerator
("DiagramGenerator",
"Set the diagram generator.",
&MatchboxFactory::theDiagramGenerator, false, false, true, true, false);
interfaceDiagramGenerator.rank(-1);
static Reference<MatchboxFactory,ProcessData> interfaceProcessData
("ProcessData",
"Set the process data object to be used.",
&MatchboxFactory::theProcessData, false, false, true, true, false);
interfaceProcessData.rank(-1);
static Parameter<MatchboxFactory,unsigned int> interfaceOrderInAlphaS
("OrderInAlphaS",
"The order in alpha_s to consider.",
&MatchboxFactory::theOrderInAlphaS, 0, 0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxFactory,unsigned int> interfaceOrderInAlphaEW
("OrderInAlphaEW",
"The order in alpha_EW to consider.",
&MatchboxFactory::theOrderInAlphaEW, 2, 0, 0,
false, false, Interface::lowerlim);
static Switch<MatchboxFactory,bool> interfaceBornContributions
("BornContributions",
"Switch on or off the Born contributions.",
&MatchboxFactory::theBornContributions, true, false, false);
static SwitchOption interfaceBornContributionsYes
(interfaceBornContributions,
"Yes",
"Switch on Born contributions.",
true);
static SwitchOption interfaceBornContributionsNo
(interfaceBornContributions,
"No",
"Switch off Born contributions.",
false);
static Switch<MatchboxFactory,bool> interfaceVirtualContributions
("VirtualContributions",
"Switch on or off the virtual contributions.",
&MatchboxFactory::theVirtualContributions, true, false, false);
static SwitchOption interfaceVirtualContributionsYes
(interfaceVirtualContributions,
"Yes",
"Switch on virtual contributions.",
true);
static SwitchOption interfaceVirtualContributionsNo
(interfaceVirtualContributions,
"No",
"Switch off virtual contributions.",
false);
static Switch<MatchboxFactory,bool> interfaceRealContributions
("RealContributions",
"Switch on or off the real contributions.",
&MatchboxFactory::theRealContributions, true, false, false);
static SwitchOption interfaceRealContributionsYes
(interfaceRealContributions,
"Yes",
"Switch on real contributions.",
true);
static SwitchOption interfaceRealContributionsNo
(interfaceRealContributions,
"No",
"Switch off real contributions.",
false);
static Switch<MatchboxFactory,bool> interfaceIndependentVirtuals
("IndependentVirtuals",
"Switch on or off virtual contributions as separate subprocesses.",
&MatchboxFactory::theIndependentVirtuals, true, false, false);
static SwitchOption interfaceIndependentVirtualsYes
(interfaceIndependentVirtuals,
"Yes",
"Switch on virtual contributions as separate subprocesses.",
true);
static SwitchOption interfaceIndependentVirtualsNo
(interfaceIndependentVirtuals,
"No",
"Switch off virtual contributions as separate subprocesses.",
false);
static Switch<MatchboxFactory,bool> interfaceIndependentPKs
("IndependentPKOperators",
"Switch on or off PK oeprators as separate subprocesses.",
&MatchboxFactory::theIndependentPKs, true, false, false);
static SwitchOption interfaceIndependentPKsYes
(interfaceIndependentPKs,
"Yes",
"Switch on PK operators as separate subprocesses.",
true);
static SwitchOption interfaceIndependentPKsNo
(interfaceIndependentPKs,
"No",
"Switch off PK operators as separate subprocesses.",
false);
static Reference<MatchboxFactory,MatchboxPhasespace> interfacePhasespace
("Phasespace",
"Set the phasespace generator.",
&MatchboxFactory::thePhasespace, false, false, true, true, false);
static Reference<MatchboxFactory,MatchboxScaleChoice> interfaceScaleChoice
("ScaleChoice",
"Set the scale choice object.",
&MatchboxFactory::theScaleChoice, false, false, true, true, false);
static Parameter<MatchboxFactory,double> interfaceFactorizationScaleFactor
("FactorizationScaleFactor",
"The factorization scale factor.",
&MatchboxFactory::theFactorizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<MatchboxFactory,double> interfaceRenormalizationScaleFactor
("RenormalizationScaleFactor",
"The renormalization scale factor.",
&MatchboxFactory::theRenormalizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Switch<MatchboxFactory,bool> interfaceFixedCouplings
("FixedCouplings",
"Switch on or off fixed couplings.",
&MatchboxFactory::theFixedCouplings, true, false, false);
static SwitchOption interfaceFixedCouplingsYes
(interfaceFixedCouplings,
"Yes",
"Yes",
true);
static SwitchOption interfaceFixedCouplingsNo
(interfaceFixedCouplings,
"No",
"No",
false);
interfaceFixedCouplings.rank(-1);
static Switch<MatchboxFactory,bool> interfaceFixedQEDCouplings
("FixedQEDCouplings",
"Switch on or off fixed QED couplings.",
&MatchboxFactory::theFixedQEDCouplings, true, false, false);
static SwitchOption interfaceFixedQEDCouplingsYes
(interfaceFixedQEDCouplings,
"Yes",
"Yes",
true);
static SwitchOption interfaceFixedQEDCouplingsNo
(interfaceFixedQEDCouplings,
"No",
"No",
false);
interfaceFixedQEDCouplings.rank(-1);
// @TDOO SP to remove this in the code as well
/*
static Switch<MatchboxFactory,bool> interfaceVetoScales
("VetoScales",
"Switch on or setting veto scales.",
&MatchboxFactory::theVetoScales, false, false, false);
static SwitchOption interfaceVetoScalesYes
(interfaceVetoScales,
"Yes",
"Yes",
true);
static SwitchOption interfaceVetoScalesNo
(interfaceVetoScales,
"No",
"No",
false);
*/
static RefVector<MatchboxFactory,MatchboxAmplitude> interfaceAmplitudes
("Amplitudes",
"The amplitude objects.",
&MatchboxFactory::theAmplitudes, -1, false, false, true, true, false);
static Switch<MatchboxFactory,bool> interfaceVerbose
("Verbose",
"Print full infomation on each evaluated phase space point.",
&MatchboxFactory::theVerbose, false, false, false);
static SwitchOption interfaceVerboseYes
(interfaceVerbose,
"Yes",
"Yes",
true);
static SwitchOption interfaceVerboseNo
(interfaceVerbose,
"No",
"No",
false);
interfaceVerbose.rank(-1);
static Switch<MatchboxFactory,bool> interfaceInitVerbose
("InitVerbose",
"Print setup information.",
&MatchboxFactory::theInitVerbose, false, false, false);
static SwitchOption interfaceInitVerboseYes
(interfaceInitVerbose,
"Yes",
"Yes",
true);
static SwitchOption interfaceInitVerboseNo
(interfaceInitVerbose,
"No",
"No",
false);
interfaceInitVerbose.rank(-1);
static Parameter<MatchboxFactory,string> interfaceSubtractionData
("SubtractionData",
"Prefix for subtraction check data.",
&MatchboxFactory::theSubtractionData, "",
false, false);
static Switch<MatchboxFactory,int> interfaceSubtractionPlotType
("SubtractionPlotType",
"Switch for controlling what kind of plot is generated for checking the subtraction",
&MatchboxFactory::theSubtractionPlotType, 1, false, false);
static SwitchOption interfaceSubtractionPlotTypeLinearRatio
(interfaceSubtractionPlotType,
"LinRatio",
"Switch on the linear plot of the ratio",
1);
static SwitchOption interfaceSubtractionPlotTypeLogRelDiff
(interfaceSubtractionPlotType,
"LogRelDiff",
"Switch on the logarithmic plot of the relative difference",
2);
static Switch<MatchboxFactory,bool> interfaceSubtractionScatterPlot
("SubtractionScatterPlot",
"Switch for controlling whether subtraction data should be plotted for each phase space point individually",
&MatchboxFactory::theSubtractionScatterPlot, false, false, false);
static SwitchOption interfaceSubtractionScatterPlotNo
(interfaceSubtractionScatterPlot,
"No", "Switch off the scatter plot", false);
static SwitchOption interfaceSubtractionScatterPlotYes
(interfaceSubtractionScatterPlot,
"Yes", "Switch on the scatter plot", true);
static Parameter<MatchboxFactory,string> interfacePoleData
("PoleData",
"Prefix for subtraction check data.",
&MatchboxFactory::thePoleData, "",
false, false);
static RefVector<MatchboxFactory,ParticleData> interfaceParticleGroup
("ParticleGroup",
"The particle group just started.",
&MatchboxFactory::particleGroup, -1, false, false, true, false, false);
static Command<MatchboxFactory> interfaceStartParticleGroup
("StartParticleGroup",
"Start a particle group.",
&MatchboxFactory::startParticleGroup, false);
static Command<MatchboxFactory> interfaceEndParticleGroup
("EndParticleGroup",
"End a particle group.",
&MatchboxFactory::endParticleGroup, false);
static Command<MatchboxFactory> interfaceProcess
("Process",
"Set the process(es) to consider.",
&MatchboxFactory::doProcess, false);
static Command<MatchboxFactory> interfaceLoopInducedProcess
("LoopInducedProcess",
"Set the loop induced process(es) to consider.",
&MatchboxFactory::doLoopInducedProcess, false);
static Command<MatchboxFactory> interfaceSingleRealProcess
("SingleRealProcess",
"Set the real emission process(es) to consider.",
&MatchboxFactory::doSingleRealProcess, false);
static Reference<MatchboxFactory,ShowerApproximation> interfaceShowerApproximation
("ShowerApproximation",
"Set the shower approximation to be considered.",
&MatchboxFactory::theShowerApproximation, false, false, true, true, false);
static Switch<MatchboxFactory,bool> interfaceRealEmissionScales
("RealEmissionScales",
"Switch on or off calculation of subtraction scales from real emission kinematics.",
&MatchboxFactory::theRealEmissionScales, false, false, false);
static SwitchOption interfaceRealEmissionScalesYes
(interfaceRealEmissionScales,
"Yes",
"Yes",
true);
static SwitchOption interfaceRealEmissionScalesNo
(interfaceRealEmissionScales,
"No",
"No",
false);
interfaceRealEmissionScales.rank(-1);
static Switch<MatchboxFactory,bool> interfaceAllProcesses
("AllProcesses",
"Consider all processes up to a maximum coupling order specified by the coupling order interfaces.",
&MatchboxFactory::theAllProcesses, false, false, false);
static SwitchOption interfaceAllProcessesYes
(interfaceAllProcesses,
"Yes",
"Include all processes.",
true);
static SwitchOption interfaceAllProcessesNo
(interfaceAllProcesses,
"No",
"Only consider processes matching the exact order in the couplings.",
false);
interfaceAllProcesses.rank(-1);
static RefVector<MatchboxFactory,MatchboxAmplitude> interfaceSelectAmplitudes
("SelectAmplitudes",
"The amplitude objects to be favoured in clashing responsibilities.",
&MatchboxFactory::theSelectedAmplitudes, -1, false, false, true, true, false);
static RefVector<MatchboxFactory,MatchboxAmplitude> interfaceDeselectAmplitudes
("DeselectAmplitudes",
"The amplitude objects to be disfavoured in clashing responsibilities.",
&MatchboxFactory::theDeselectedAmplitudes, -1, false, false, true, true, false);
static Switch<MatchboxFactory,int> interfaceDipoleSet
("DipoleSet",
"The set of subtraction terms to be considered.",
&MatchboxFactory::theDipoleSet, 0, false, false);
static SwitchOption interfaceDipoleSetCataniSeymour
(interfaceDipoleSet,
"CataniSeymour",
"Use default Catani-Seymour dipoles.",
0);
interfaceDipoleSet.rank(-1);
static RefVector<MatchboxFactory,ReweightBase> interfaceReweighters
("Reweighters",
"Reweight objects for matrix elements.",
&MatchboxFactory::theReweighters, -1, false, false, true, false, false);
static RefVector<MatchboxFactory,ReweightBase> interfacePreweighters
("Preweighters",
"Preweight objects for matrix elements.",
&MatchboxFactory::thePreweighters, -1, false, false, true, false, false);
static Switch<MatchboxFactory,bool> interfaceMECorrectionsOnly
("MECorrectionsOnly",
"Prepare only ME corrections, but no NLO calculation.",
&MatchboxFactory::theMECorrectionsOnly, false, false, false);
static SwitchOption interfaceMECorrectionsOnlyYes
(interfaceMECorrectionsOnly,
"Yes",
"Produce only ME corrections.",
true);
static SwitchOption interfaceMECorrectionsOnlyNo
(interfaceMECorrectionsOnly,
"No",
"Produce full NLO.",
false);
static Switch<MatchboxFactory,bool> interfaceLoopSimCorrections
("LoopSimCorrections",
"Prepare LoopSim corrections.",
&MatchboxFactory::theLoopSimCorrections, false, false, false);
static SwitchOption interfaceLoopSimCorrectionsYes
(interfaceLoopSimCorrections,
"Yes",
"Produce loopsim corrections.",
true);
static SwitchOption interfaceLoopSimCorrectionsNo
(interfaceLoopSimCorrections,
"No",
"Produce full NLO.",
false);
static Switch<MatchboxFactory,bool> interfaceFirstPerturbativePDF
("FirstPerturbativePDF",
"",
&MatchboxFactory::theFirstPerturbativePDF, true, false, false);
static SwitchOption interfaceFirstPerturbativePDFYes
(interfaceFirstPerturbativePDF,
"Yes",
"",
true);
static SwitchOption interfaceFirstPerturbativePDFNo
(interfaceFirstPerturbativePDF,
"No",
"",
false);
interfaceFirstPerturbativePDF.rank(-1);
static Switch<MatchboxFactory,bool> interfaceSecondPerturbativePDF
("SecondPerturbativePDF",
"",
&MatchboxFactory::theSecondPerturbativePDF, true, false, false);
static SwitchOption interfaceSecondPerturbativePDFYes
(interfaceSecondPerturbativePDF,
"Yes",
"",
true);
static SwitchOption interfaceSecondPerturbativePDFNo
(interfaceSecondPerturbativePDF,
"No",
"",
false);
interfaceSecondPerturbativePDF.rank(-1);
static Command<MatchboxFactory> interfaceProductionMode
("ProductionMode",
"Switch this factory to production mode.",
&MatchboxFactory::doProductionMode, false);
static Switch<MatchboxFactory,bool> interfaceSpinCorrelations
("SpinCorrelations",
"Fill information for the spin correlations, if possible.",
&MatchboxFactory::theSpinCorrelations, false, false, false);
static SwitchOption interfaceSpinCorrelationsYes
(interfaceSpinCorrelations,
"Yes",
"",
true);
static SwitchOption interfaceSpinCorrelationsNo
(interfaceSpinCorrelations,
"No",
"",
false);
static Parameter<MatchboxFactory,double> interfaceAlphaParameter
("AlphaParameter",
"Nagy-AlphaParameter.",
&MatchboxFactory::theAlphaParameter, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Switch<MatchboxFactory,bool> interfaceEnforceChargeConservation
("EnforceChargeConservation",
"Enforce charge conservation while generating the hard process.",
&MatchboxFactory::theEnforceChargeConservation, true, false, false);
static SwitchOption interfaceEnforceChargeConservationYes
(interfaceEnforceChargeConservation,
"Yes",
"Enforce charge conservation.",
true);
static SwitchOption interfaceEnforceChargeConservationNo
(interfaceEnforceChargeConservation,
"No",
"Do not enforce charge conservation.",
false);
interfaceEnforceChargeConservation.rank(-1);
static Switch<MatchboxFactory,bool> interfaceEnforceColourConservation
("EnforceColourConservation",
"Enforce colour conservation while generating the hard process.",
&MatchboxFactory::theEnforceColourConservation, false, false, false);
static SwitchOption interfaceEnforceColourConservationYes
(interfaceEnforceColourConservation,
"Yes",
"Enforce colour conservation.",
true);
static SwitchOption interfaceEnforceColourConservationNo
(interfaceEnforceColourConservation,
"No",
"Do not enforce colour conservation.",
false);
interfaceEnforceColourConservation.rank(-1);
static Switch<MatchboxFactory,bool> interfaceEnforceLeptonNumberConservation
("EnforceLeptonNumberConservation",
"Enforce lepton number conservation while generating the hard process.",
&MatchboxFactory::theEnforceLeptonNumberConservation, false, false, false);
static SwitchOption interfaceEnforceLeptonNumberConservationYes
(interfaceEnforceLeptonNumberConservation,
"Yes",
"Enforce lepton number conservation.",
true);
static SwitchOption interfaceEnforceLeptonNumberConservationNo
(interfaceEnforceLeptonNumberConservation,
"No",
"Do not enforce lepton number conservation.",
false);
interfaceEnforceLeptonNumberConservation.rank(-1);
static Switch<MatchboxFactory,bool> interfaceEnforceQuarkNumberConservation
("EnforceQuarkNumberConservation",
"Enforce quark number conservation while generating the hard process.",
&MatchboxFactory::theEnforceQuarkNumberConservation, false, false, false);
static SwitchOption interfaceEnforceQuarkNumberConservationYes
(interfaceEnforceQuarkNumberConservation,
"Yes",
"Enforce quark number conservation.",
true);
static SwitchOption interfaceEnforceQuarkNumberConservationNo
(interfaceEnforceQuarkNumberConservation,
"No",
"Do not enforce quark number conservation.",
false);
interfaceEnforceQuarkNumberConservation.rank(-1);
static Switch<MatchboxFactory,bool> interfaceLeptonFlavourDiagonal
("LeptonFlavourDiagonal",
"Assume that lepton interactions are flavour diagonal while generating the hard process.",
&MatchboxFactory::theLeptonFlavourDiagonal, false, false, false);
static SwitchOption interfaceLeptonFlavourDiagonalYes
(interfaceLeptonFlavourDiagonal,
"Yes",
"Assume that lepton interactions are flavour diagonal.",
true);
static SwitchOption interfaceLeptonFlavourDiagonalNo
(interfaceLeptonFlavourDiagonal,
"No",
"Do not assume that lepton interactions are flavour diagonal.",
false);
interfaceLeptonFlavourDiagonal.rank(-1);
static Switch<MatchboxFactory,bool> interfaceQuarkFlavourDiagonal
("QuarkFlavourDiagonal",
"Assume that quark interactions are flavour diagonal while generating the hard process.",
&MatchboxFactory::theQuarkFlavourDiagonal, false, false, false);
static SwitchOption interfaceQuarkFlavourDiagonalYes
(interfaceQuarkFlavourDiagonal,
"Yes",
"Assume that quark interactions are flavour diagonal.",
true);
static SwitchOption interfaceQuarkFlavourDiagonalNo
(interfaceQuarkFlavourDiagonal,
"No",
"Do not assume that quark interactions are flavour diagonal.",
false);
interfaceQuarkFlavourDiagonal.rank(-1);
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxFactory,SubProcessHandler>
describeHerwigMatchboxFactory("Herwig::MatchboxFactory", "Herwig.so");
diff --git a/MatrixElement/Matchbox/MatchboxFactory.h b/MatrixElement/Matchbox/MatchboxFactory.h
--- a/MatrixElement/Matchbox/MatchboxFactory.h
+++ b/MatrixElement/Matchbox/MatchboxFactory.h
@@ -1,1305 +1,1297 @@
// -*- C++ -*-
//
// MatchboxFactory.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MatchboxFactory_H
#define HERWIG_MatchboxFactory_H
//
// This is the declaration of the MatchboxFactory class.
//
#include "ThePEG/Handlers/SubProcessHandler.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxAmplitude.h"
#include "Herwig/MatrixElement/Matchbox/Utility/Tree2toNGenerator.h"
#include "Herwig/MatrixElement/Matchbox/Utility/ProcessData.h"
#include "Herwig/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
#include "Herwig/MatrixElement/Matchbox/Base/SubtractedME.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.fh"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxFactory automatically sets up a NLO
* QCD calculation carried out in dipole subtraction.
*
* @see \ref MatchboxFactoryInterfaces "The interfaces"
* defined for MatchboxFactory.
*/
class MatchboxFactory: public SubProcessHandler {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxFactory();
- /**
- * The destructor.
- */
- virtual ~MatchboxFactory();
- //@}
-
public:
/**
* Pointer to the current factory object
*/
static const Ptr<MatchboxFactory>::tptr currentFactory() {
assert(theCurrentFactory);
return theCurrentFactory;
}
private:
/**
* Pointer to the current factory object
*/
static Ptr<MatchboxFactory>::tptr theCurrentFactory;
public:
/**
* Flag to indicate that at least one MatchboxFactory object is in action
*/
static bool isMatchboxRun() {
return theIsMatchboxRun();
}
/** @name Process and diagram information */
//@{
/**
* Return the diagram generator.
*/
Ptr<Tree2toNGenerator>::tptr diagramGenerator() const { return theDiagramGenerator; }
/**
* Set the diagram generator.
*/
void diagramGenerator(Ptr<Tree2toNGenerator>::ptr dg) { theDiagramGenerator = dg; }
/**
* Return the process data.
*/
Ptr<ProcessData>::tptr processData() const { return theProcessData; }
/**
* Set the process data.
*/
void processData(Ptr<ProcessData>::ptr pd) { theProcessData = pd; }
/**
* Return the number of light flavours, this matrix
* element is calculated for.
*/
unsigned int nLight() const { return theNLight; }
/**
* Set the number of light flavours, this matrix
* element is calculated for.
*/
void nLight(unsigned int n) { theNLight = n; }
/**
* Return the vector that contains the PDG ids of
* the light flavours, which are contained in the
* jet particle group.
*/
vector<long> nLightJetVec() const { return theNLightJetVec; }
/**
* Set the elements of the vector that contains the PDG
* ids of the light flavours, which are contained in the
* jet particle group.
*/
void nLightJetVec(long n) { theNLightJetVec.push_back(n); }
/**
* Return the vector that contains the PDG ids of
* the heavy flavours, which are contained in the
* jet particle group.
*/
vector<long> nHeavyJetVec() const { return theNHeavyJetVec; }
/**
* Set the elements of the vector that contains the PDG
* ids of the heavy flavours, which are contained in the
* jet particle group.
*/
void nHeavyJetVec(long n) { theNHeavyJetVec.push_back(n); }
/**
* Return the vector that contains the PDG ids of
* the light flavours, which are contained in the
* proton particle group.
*/
vector<long> nLightProtonVec() const { return theNLightProtonVec; }
/**
* Set the elements of the vector that contains the PDG
* ids of the light flavours, which are contained in the
* proton particle group.
*/
void nLightProtonVec(long n) { theNLightProtonVec.push_back(n); }
/**
* Return the order in \f$\alpha_S\f$.
*/
unsigned int orderInAlphaS() const { return theOrderInAlphaS; }
/**
* Set the order in \f$\alpha_S\f$.
*/
void orderInAlphaS(unsigned int o) { theOrderInAlphaS = o; }
/**
* Return the order in \f$\alpha_{EM}\f$.
*/
unsigned int orderInAlphaEW() const { return theOrderInAlphaEW; }
/**
* Set the order in \f$\alpha_{EM}\f$.
*/
void orderInAlphaEW(unsigned int o) { theOrderInAlphaEW = o; }
/**
* The multiplicity of legs with virtual contributions.
*/
size_t highestVirt() const {return theHighestVirtualSize;}
/**
* Set the highest
**/
void setHighestVirt(size_t n){theHighestVirtualSize=n;}
/**
* Access the processes vector.
*/
const vector<vector<string> > getProcesses() const {return processes;}
/**
* Return true, if all processes up to a maximum order are considered
*/
bool allProcesses() const { return theAllProcesses; }
/**
* Switch on/off inclusino off all processes up to a maximum order
*/
void setAllProcesses(bool on = true) { theAllProcesses = on; }
/**
* Return true, if Born contributions should be included.
*/
bool bornContributions() const { return theBornContributions; }
/**
* Switch on or off Born contributions
*/
void setBornContributions(bool on = true) { theBornContributions = on; }
/**
* Return true, if virtual contributions should be included.
*/
bool virtualContributions() const { return theVirtualContributions; }
/**
* Switch on or off virtual contributions
*/
void setVirtualContributions(bool on = true) { theVirtualContributions = on; }
/**
* Produce matrix element corrections, but no NLO
*/
bool meCorrectionsOnly() const { return theMECorrectionsOnly; }
/**
* Switch to produce matrix element corrections, but no NLO
*/
void setMECorrectionsOnly(bool on = true) { theMECorrectionsOnly = on; }
/**
* Produce matrix element corrections, with LoopSim NLO
*/
bool loopSimCorrections() const { return theLoopSimCorrections; }
/**
* Switch to produce matrix element corrections, with LoopSim NLO
*/
void setLoopSimCorrections(bool on = true) { theLoopSimCorrections = on; }
/**
* Return true, if subtracted real emission contributions should be included.
*/
bool realContributions() const { return theRealContributions; }
/**
* Switch on or off subtracted real emission contributions
*/
void setRealContributions(bool on = true) { theRealContributions = on; }
/**
* Return true, if virtual contributions should be treated as independent subprocesses
*/
bool independentVirtuals() const { return theIndependentVirtuals; }
/**
* Switch on/off virtual contributions should be treated as independent subprocesses
*/
void setIndependentVirtuals(bool on = true) { theIndependentVirtuals = on; }
/**
* Return true, if PK operator contributions should be treated as independent subprocesses
*/
bool independentPKs() const { return theIndependentPKs; }
/**
* Switch on/off PK operator contributions should be treated as independent subprocesses
*/
void setIndependentPKs(bool on = true) { theIndependentPKs = on; }
/**
* Return true, if SubProcessGroups should be
* setup from this MEGroup. If not, a single SubProcess
* is constructed from the data provided by the
* head matrix element.
*/
virtual bool subProcessGroups() const { return !showerApproximation(); }
/**
* Return true, if subtraction scales should be caluclated from real emission kinematics
*/
bool realEmissionScales() const { return theRealEmissionScales; }
/**
* Switch on/off that subtraction scales should be caluclated from real emission kinematics
*/
void setRealEmissionScales(bool on = true) { theRealEmissionScales = on; }
/**
* Set the shower approximation.
*/
void showerApproximation(Ptr<ShowerApproximation>::tptr app) { theShowerApproximation = app; }
/**
* Return the shower approximation.
*/
Ptr<ShowerApproximation>::tptr showerApproximation() const { return theShowerApproximation; }
//@}
/** @name Phasespace generation and scale choice */
//@{
/**
* 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 scale choice object
*/
void scaleChoice(Ptr<MatchboxScaleChoice>::ptr sc) { theScaleChoice = sc; }
/**
* Return the scale choice object
*/
Ptr<MatchboxScaleChoice>::tptr scaleChoice() const { return theScaleChoice; }
/**
* Get the factorization scale factor
*/
double factorizationScaleFactor() const { return theFactorizationScaleFactor; }
/**
* Set the factorization scale factor
*/
void factorizationScaleFactor(double f) { theFactorizationScaleFactor = f; }
/**
* Get the renormalization scale factor
*/
double renormalizationScaleFactor() const { return theRenormalizationScaleFactor; }
/**
* Set the renormalization scale factor
*/
void renormalizationScaleFactor(double f) { theRenormalizationScaleFactor = f; }
/**
* Return true, if fixed couplings are used.
*/
bool fixedCouplings() const { return theFixedCouplings; }
/**
* Switch on fixed couplings.
*/
void setFixedCouplings(bool on = true) { theFixedCouplings = on; }
/**
* Return true, if fixed couplings are used.
*/
bool fixedQEDCouplings() const { return theFixedQEDCouplings; }
/**
* Switch on fixed couplings.
*/
void setFixedQEDCouplings(bool on = true) { theFixedQEDCouplings = on; }
/**
* Return true, if veto scales should be set
* for the real emission
*/
bool vetoScales() const { return theVetoScales; }
/**
* Switch on setting veto scales
*/
void doVetoScales() { theVetoScales = true; }
/**
* Switch off setting veto scales
*/
void noVetoScales() { theVetoScales = true; }
//@}
/** @name Amplitudes and caching */
//@{
/**
* Return the amplitudes to be considered
*/
const vector<Ptr<MatchboxAmplitude>::ptr>& amplitudes() const { return theAmplitudes; }
/**
* Access the amplitudes to be considered
*/
vector<Ptr<MatchboxAmplitude>::ptr>& amplitudes() { return theAmplitudes; }
//@}
/** @name Matrix element objects. */
//@{
/**
* Return the Born matrix elements to be considered
*/
const vector<Ptr<MatchboxMEBase>::ptr>& bornMEs() const { return theBornMEs; }
/**
* Access the Born matrix elements to be considered
*/
vector<Ptr<MatchboxMEBase>::ptr>& bornMEs() { return theBornMEs; }
/**
* Return the loop induced matrix elements to be considered
*/
const vector<Ptr<MatchboxMEBase>::ptr>& loopInducedMEs() const { return theLoopInducedMEs; }
/**
* Access the loop induced matrix elements to be considered
*/
vector<Ptr<MatchboxMEBase>::ptr>& loopInducedMEs() { return theLoopInducedMEs; }
/**
* Return the processes to be ordered from an OLP
*/
const map<Ptr<MatchboxAmplitude>::tptr,
map<pair<Process,int>,int> >&
olpProcesses() const { return theOLPProcesses; }
/**
* Access the processes to be ordered from an OLP
*/
map<Ptr<MatchboxAmplitude>::tptr,
map<pair<Process,int>,int> >&
olpProcesses() { return theOLPProcesses; }
/**
* Order an OLP process and return its id
*/
int orderOLPProcess(const Process& p,
Ptr<MatchboxAmplitude>::tptr amp,
int type);
/**
* Return the amplitudes which need external initialization
*/
const set<Ptr<MatchboxAmplitude>::tptr>& externalAmplitudes() const {
return theExternalAmplitudes;
}
/**
* Access the amplitudes which need external initialization
*/
set<Ptr<MatchboxAmplitude>::tptr>& externalAmplitudes() {
return theExternalAmplitudes;
}
/**
* Return the virtual corrections to be considered
*/
const vector<Ptr<MatchboxInsertionOperator>::ptr>& virtuals() const { return theVirtuals; }
/**
* Access the virtual corrections to be considered
*/
vector<Ptr<MatchboxInsertionOperator>::ptr>& virtuals() { return theVirtuals; }
/**
* Return the produced NLO matrix elements
*/
const vector<Ptr<MatchboxMEBase>::ptr>& bornVirtualMEs() const { return theBornVirtualMEs; }
/**
* Access the produced NLO matrix elements
*/
vector<Ptr<MatchboxMEBase>::ptr>& bornVirtualMEs() { return theBornVirtualMEs; }
/**
* Return the real emission matrix elements to be considered
*/
const vector<Ptr<MatchboxMEBase>::ptr>& realEmissionMEs() const { return theRealEmissionMEs; }
/**
* Access the real emission matrix elements to be considered
*/
vector<Ptr<MatchboxMEBase>::ptr>& realEmissionMEs() { return theRealEmissionMEs; }
/**
* Return, which set of dipoles should be considered
*/
int dipoleSet() const { return theDipoleSet; }
/**
* Return, which set of dipoles should be considered
*/
void dipoleSet(int s) { theDipoleSet = s; }
/**
* Return the produced subtracted matrix elements
*/
const vector<Ptr<SubtractedME>::ptr>& subtractedMEs() const { return theSubtractedMEs; }
/**
* Access the produced subtracted matrix elements
*/
vector<Ptr<SubtractedME>::ptr>& subtractedMEs() { return theSubtractedMEs; }
/**
* Return the produced finite real emission matrix elements
*/
const vector<Ptr<MatchboxMEBase>::ptr>& finiteRealMEs() const { return theFiniteRealMEs; }
/**
* Access the produced finite real emission elements
*/
vector<Ptr<MatchboxMEBase>::ptr>& finiteRealMEs() { return theFiniteRealMEs; }
/**
* Return the map of Born processes to splitting dipoles
*/
const map<cPDVector,set<Ptr<SubtractionDipole>::ptr> >& splittingDipoles() const {
return theSplittingDipoles;
}
/**
* Identify a splitting channel
*/
struct SplittingChannel {
/**
* The Born XComb
*/
StdXCombPtr bornXComb;
/**
* The real XComb
*/
StdXCombPtr realXComb;
/**
* The set of tilde XCombs to consider for the real xcomb
*/
vector<StdXCombPtr> tildeXCombs;
/**
* The dipole in charge of the splitting
*/
Ptr<SubtractionDipole>::ptr dipole;
/**
* Dump the setup
*/
void print(ostream&) const;
};
/**
* Generate all splitting channels for the Born process handled by
* the given XComb
*/
list<SplittingChannel> getSplittingChannels(tStdXCombPtr xc) const;
/**
* Return the reweight objects for matrix elements
*/
const vector<ReweightPtr>& reweighters() const { return theReweighters; }
/**
* Access the reweight objects for matrix elements
*/
vector<ReweightPtr>& reweighters() { return theReweighters; }
/**
* Return the preweight objects for matrix elements
*/
const vector<ReweightPtr>& preweighters() const { return thePreweighters; }
/**
* Access the preweight objects for matrix elements
*/
vector<ReweightPtr>& preweighters() { return thePreweighters; }
//@}
/** @name Setup the matrix elements */
//@{
/**
* 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; }
/**
* Prepare a matrix element.
*/
void prepareME(Ptr<MatchboxMEBase>::ptr);
/**
* Check consistency and switch to porduction mode.
*/
virtual void productionMode();
/**
* Setup everything
*/
virtual void setup();
/**
* The highest multiplicity of legs having virtual contributions.(needed for madgraph)
*/
size_t highestVirt(){return theHighestVirtualsize;}
//@}
/** @name Diagnostic information */
//@{
/**
* Return true, if verbose
*/
bool verbose() const { return theVerbose; }
/**
* Switch on diagnostic information.
*/
void setVerbose(bool on = true) { theVerbose = on; }
/**
* Return true, if verbose while initializing
*/
bool initVerbose() const { return theInitVerbose || verbose(); }
/**
* Switch on diagnostic information while initializing
*/
void setInitVerbose(bool on = true) { theInitVerbose = on; }
/**
* Dump the setup
*/
void print(ostream&) const;
/**
* Return the subtraction data prefix.
*/
const string& subtractionData() const { return theSubtractionData; }
/**
* Set the subtraction data prefix.
*/
void subtractionData(const string& s) { theSubtractionData = s; }
/**
* Return the subtraction plot type.
*/
const int& subtractionPlotType() const { return theSubtractionPlotType; }
/**
* Set the subtraction plot type.
*/
void subtractionPlotType(const int& t) { theSubtractionPlotType = t; }
/**
* Return whether subtraction data should be plotted for all phase space points individually
*/
const bool& subtractionScatterPlot() const { return theSubtractionScatterPlot; }
/**
* Set whether subtraction data should be plotted for all phase space points individually
*/
void subtractionScatterPlot(const bool& s) { theSubtractionScatterPlot = s; }
/**
* Return the pole data prefix.
*/
const string& poleData() const { return thePoleData; }
/**
* Set the pole data prefix.
*/
void poleData(const string& s) { thePoleData = s; }
/**
* Return true, if cancellationn of epsilon poles should be checked.
*/
bool checkPoles() const { return poleData() != ""; }
//@}
/** @name Process generation */
//@{
/**
* Return the particle groups.
*/
const map<string,PDVector>& particleGroups() const { return theParticleGroups; }
/**
* Access the particle groups.
*/
map<string,PDVector>& particleGroups() { return theParticleGroups; }
/**
* Return true, if the given particle is incoming
*/
bool isIncoming(cPDPtr p) const {
return theIncoming.find(p->id()) != theIncoming.end();
}
/**
* Return true, if spin correlation information should be provided, if possible.
*/
bool spinCorrelations() const { return theSpinCorrelations; }
/**
* Indicate that spin correlation information should be provided, if possible.
*/
void setSpinCorrelations(bool yes) { theSpinCorrelations = yes; }
//@}
/** @name Truncated qtilde shower information */
//@{
/**
* Return the subprocess of the real emission
*/
tSubProPtr hardTreeSubprocess() { return theHardtreeSubprocess; }
/**
* Set the subprocess of the real emission for use in calculating the shower hardtree
*/
void setHardTreeSubprocess(tSubProPtr hardTree) { theHardtreeSubprocess = hardTree; }
/**
* Return the born emitter
*/
int hardTreeEmitter() { return theHardtreeEmitter; }
/**
* Set the born emitter for use in calculating the shower hardtree
*/
void setHardTreeEmitter(int emitter) { theHardtreeEmitter = emitter; }
/**
* Return the born spectator
*/
int hardTreeSpectator() { return theHardtreeSpectator; }
/**
* Set the born spectator for use in calculating the shower hardtree
*/
void setHardTreeSpectator(int spectator) { theHardtreeSpectator = spectator; }
//@}
/** @name Data handling */
//@{
/**
* Return (and possibly create) a directory to contain amplitude
* information.
*/
const string& buildStorage();
/**
* Return (and possibly create) a directory to contain integration grid
* information.
*/
const string& runStorage();
/**
* alpha of http://arxiv.org/pdf/hep-ph/0307268v2.pdf to restrict
* dipole phase space
*/
double alphaParameter() const { return theAlphaParameter; }
/**
* set the alpha parameter (needed for massive PK-Operator)
*/
void setAlphaParameter(double a)const { theAlphaParameter = a; }
//@}
public:
/**
* Print a summary of the parameters used
*/
void summary(ostream&) 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;
//@}
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:
/**
* Flag to indicate that at least one MatchboxFactory object is in action
*/
static bool& theIsMatchboxRun();
/**
* The diagram generator.
*/
Ptr<Tree2toNGenerator>::ptr theDiagramGenerator;
/**
* The process data object to be used
*/
Ptr<ProcessData>::ptr theProcessData;
/**
* The number of light flavours, this matrix
* element is calculated for.
*/
unsigned int theNLight;
/**
* Vector with the PDG ids of the light quark flavours,
* which are contained in the jet particle group.
*/
vector<long> theNLightJetVec;
/**
* Vector with the PDG ids of the heavy quark flavours,
* which are contained in the jet particle group.
*/
vector<long> theNHeavyJetVec;
/**
* Vector with the PDG ids of the light quark flavours,
* which are contained in the proton particle group.
*/
vector<long> theNLightProtonVec;
/**
* The order in \f$\alpha_S\f$.
*/
unsigned int theOrderInAlphaS;
/**
* The order in \f$\alpha_{EM}\f$.
*/
unsigned int theOrderInAlphaEW;
/**
* The maximum number of legs with virtual corrections.
**/
unsigned int theHighestVirtualSize;
/**
* Switch on or off Born contributions
*/
bool theBornContributions;
/**
* Switch on or off virtual contributions
*/
bool theVirtualContributions;
/**
* Switch on or off subtracted real emission contributions should be included.
*/
bool theRealContributions;
/**
* True if virtual contributions should be treated as independent subprocesses
*/
bool theIndependentVirtuals;
/**
* True if PK operator contributions should be treated as independent subprocesses
*/
bool theIndependentPKs;
/**
* The phase space generator to be used.
*/
Ptr<MatchboxPhasespace>::ptr thePhasespace;
/**
* The scale choice object
*/
Ptr<MatchboxScaleChoice>::ptr theScaleChoice;
/**
* The factorization scale factor.
*/
double theFactorizationScaleFactor;
/**
* The renormalization scale factor.
*/
double theRenormalizationScaleFactor;
/**
* Use non-running couplings.
*/
bool theFixedCouplings;
/**
* Use non-running couplings.
*/
bool theFixedQEDCouplings;
/**
* True, if veto scales should be set
* for the real emission
*/
bool theVetoScales;
/**
* The amplitudes to be considered
*/
vector<Ptr<MatchboxAmplitude>::ptr> theAmplitudes;
/**
* The Born matrix elements to be considered
*/
vector<Ptr<MatchboxMEBase>::ptr> theBornMEs;
/**
* The loop induced matrix elements to be considered
*/
vector<Ptr<MatchboxMEBase>::ptr> theLoopInducedMEs;
/**
* The virtual corrections to be considered
*/
vector<Ptr<MatchboxInsertionOperator>::ptr> theVirtuals;
/**
* The real emission matrix elements to be considered
*/
vector<Ptr<MatchboxMEBase>::ptr> theRealEmissionMEs;
/**
* The produced NLO matrix elements
*/
vector<Ptr<MatchboxMEBase>::ptr> theBornVirtualMEs;
/**
* The produced subtracted matrix elements
*/
vector<Ptr<SubtractedME>::ptr> theSubtractedMEs;
/**
* The produced finite real emission matrix elements
*/
vector<Ptr<MatchboxMEBase>::ptr> theFiniteRealMEs;
/**
* Which set of dipoles should be considered
*/
int theDipoleSet;
/**
* Switch on or off verbosity
*/
bool theVerbose;
/**
* True, if verbose while initializing
*/
bool theInitVerbose;
/**
* Prefix for subtraction data
*/
string theSubtractionData;
/**
* Set the type of plot that is to be generated for subtraction checking
*/
int theSubtractionPlotType;
/**
* Set whether subtraction data should be plotted for all phase space points individually
*/
bool theSubtractionScatterPlot;
/**
* Prefix for pole data.
*/
string thePoleData;
/**
* Command to limit the real emission process to be considered.
*/
string doSingleRealProcess(string);
/**
* The real emission process to be included; if empty, all possible
* ones will be considered.
*/
vector<vector<string> > realEmissionProcesses;
/**
* Particle groups.
*/
map<string,PDVector> theParticleGroups;
/**
* Command to start a particle group.
*/
string startParticleGroup(string);
/**
* The name of the particle group currently edited.
*/
string particleGroupName;
/**
* The particle group currently edited.
*/
PDVector particleGroup;
/**
* Command to end a particle group.
*/
string endParticleGroup(string);
protected:
/**
* Parse a process description
*/
virtual vector<string> parseProcess(string);
private:
/**
* Command to set the process.
*/
string doProcess(string);
/**
* Command to set the process.
*/
string doLoopInducedProcess(string);
/**
* The process to consider in terms of particle groups.
*/
vector<vector<string> > processes;
/**
* The loop induced process to consider in terms of particle groups.
*/
vector<vector<string> > loopInducedProcesses;
/**
* Generate subprocesses.
*/
set<PDVector> makeSubProcesses(const vector<string>&) const;
public:
/**
* Generate matrix element objects for the given process.
*/
vector<Ptr<MatchboxMEBase>::ptr> makeMEs(const vector<string>&,
unsigned int orderas,
bool virt);
private:
/**
* The shower approximation.
*/
Ptr<ShowerApproximation>::ptr theShowerApproximation;
/**
* The map of Born processes to splitting dipoles
*/
map<cPDVector,set<Ptr<SubtractionDipole>::ptr> > theSplittingDipoles;
/**
* True, if subtraction scales should be caluclated from real emission kinematics
*/
bool theRealEmissionScales;
/**
* Consider all processes with order in couplings specifying the
* maximum order.
*/
bool theAllProcesses;
/**
* The processes to be ordered from an OLP
*/
map<Ptr<MatchboxAmplitude>::tptr,map<pair<Process,int>,int> > theOLPProcesses;
/**
* Amplitudes which need external initialization
*/
set<Ptr<MatchboxAmplitude>::tptr> theExternalAmplitudes;
/**
* Amplitudes to be selected on clashing responsibilities.
*/
vector<Ptr<MatchboxAmplitude>::ptr> theSelectedAmplitudes;
/**
* Amplitudes to be deselected on clashing responsibilities.
*/
vector<Ptr<MatchboxAmplitude>::ptr> theDeselectedAmplitudes;
/**
* Reweight objects for matrix elements
*/
vector<ReweightPtr> theReweighters;
/**
* Preweight objects for matrix elements
*/
vector<ReweightPtr> thePreweighters;
/**
* Produce matrix element corrections, but no NLO
*/
bool theMECorrectionsOnly;
/**
* The highest multiplicity of legs having virtual contributions.(needed for madgraph)
*/
int theHighestVirtualsize;
/**
* Produce matrix element corrections, with LoopSim NLO
*/
bool theLoopSimCorrections;
/**
* True, if the setup has already been run.
*/
bool ranSetup;
/**
* PDG ids of incoming particles
*/
set<long> theIncoming;
/**
* True, if first incoming partons originate from perturbative PDF
*/
bool theFirstPerturbativePDF;
/**
* True, if second incoming partons originate from perturbative PDF
*/
bool theSecondPerturbativePDF;
/**
* True, if this Factory is in production mode.
*/
bool inProductionMode;
/**
* The real emission subprocess used when calculating the hardtree
* in the truncated qtilde shower
*/
tSubProPtr theHardtreeSubprocess;
/**
* The born emitter used when calculating the hardtree in
* the truncated shower
*/
int theHardtreeEmitter;
/**
* The born spectator used when calculating the hardtree in
* the truncated shower
*/
int theHardtreeSpectator;
/**
* True, if spin correlation information should be provided, if possible.
*/
bool theSpinCorrelations;
/**
* The alpha parameter to be used for the dipole subtraction
* JB: The parameter is muatble, since we need to be able to change it
* while calculating the difference of IPK with and without alpha.
*/
mutable double theAlphaParameter;
/**
* Wether or not charge conservation should be enforced for the processes
* constructed.
*/
bool theEnforceChargeConservation;
/**
* Wether or not colour conservation should be enforced for the processes
* constructed.
*/
bool theEnforceColourConservation;
/**
* Wether or not lepton number conservation should be enforced for the processes
* constructed.
*/
bool theEnforceLeptonNumberConservation;
/**
* Wether or not quark number conservation should be enforced for the processes
* constructed.
*/
bool theEnforceQuarkNumberConservation;
/**
* Assume flavour diagonal lepton interactions
*/
bool theLeptonFlavourDiagonal;
/**
* Assume flavour diagonal quark interactions
*/
bool theQuarkFlavourDiagonal;
/**
* Command for production mode
*/
string doProductionMode(string) {
productionMode(); return "";
}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxFactory & operator=(const MatchboxFactory &) = delete;
};
}
#endif /* HERWIG_MatchboxFactory_H */
diff --git a/MatrixElement/Matchbox/Matching/DipoleMatching.cc b/MatrixElement/Matchbox/Matching/DipoleMatching.cc
--- a/MatrixElement/Matchbox/Matching/DipoleMatching.cc
+++ b/MatrixElement/Matchbox/Matching/DipoleMatching.cc
@@ -1,147 +1,141 @@
// -*- C++ -*-
//
// DipoleMatching.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the DipoleMatching class.
//
#include "DipoleMatching.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
using namespace Herwig;
-DipoleMatching::DipoleMatching() {}
-
-DipoleMatching::~DipoleMatching() {}
-
IBPtr DipoleMatching::clone() const {
return new_ptr(*this);
}
IBPtr DipoleMatching::fullclone() const {
return new_ptr(*this);
}
CrossSection DipoleMatching::dSigHatDR() const {
double xme2 = 0.;
pair<int,int> ij(dipole()->bornEmitter(),
dipole()->bornSpectator());
double ccme2 =
dipole()->underlyingBornME()->largeNColourCorrelatedME2(ij,theLargeNBasis);
if(ccme2==0.)return 0.*nanobarn;
double lnme2=dipole()->underlyingBornME()->largeNME2(theLargeNBasis);
if(lnme2==0){
generator()->log() <<"\nDipoleMatching: ";
generator()->log() <<"\n LargeNME2 is ZERO, while largeNColourCorrelatedME2 is not ZERO." ;
generator()->log() <<"\n This is too seriuos.\n" ;
generator()->log() << Exception::runerror;
}
ccme2 *=
dipole()->underlyingBornME()->me2() /lnme2;
xme2 = dipole()->me2Avg(ccme2);
xme2 /= dipole()->underlyingBornME()->lastXComb().lastAlphaS();
double bornPDF = bornPDFWeight(dipole()->underlyingBornME()->lastScale());
if ( bornPDF == 0.0 )
return ZERO;
xme2 *= bornPDF;
if ( profileScales() )
xme2 *= profileScales()->hardScaleProfile(dipole()->showerHardScale(),dipole()->lastPt());
CrossSection res =
sqr(hbarc) *
realXComb()->jacobian() *
subtractionScaleWeight() *
xme2 /
(2. * realXComb()->lastSHat());
return res;
}
double DipoleMatching::me2() const {
throw Exception() << "DipoleMatching::me2(): Not intented to use. Disable the ShowerApproximationGenerator."
<< Exception::runerror;
return 0.;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleMatching::persistentOutput(PersistentOStream & os) const {
os << theShowerHandler;
}
void DipoleMatching::persistentInput(PersistentIStream & is, int) {
is >> theShowerHandler;
}
void DipoleMatching::doinit() {
if ( theShowerHandler ) {
theShowerHandler->init();
hardScaleFactor(theShowerHandler->hardScaleFactor());
factorizationScaleFactor(theShowerHandler->factorizationScaleFactor());
renormalizationScaleFactor(theShowerHandler->renormalizationScaleFactor());
profileScales(theShowerHandler->profileScales());
restrictPhasespace(theShowerHandler->restrictPhasespace());
hardScaleIsMuF(theShowerHandler->hardScaleIsMuF());
if ( theShowerHandler->showerPhaseSpaceOption() == 0 ) {
useOpenZ(false);
} else if ( theShowerHandler->showerPhaseSpaceOption() == 1 ) {
useOpenZ(true);
} else {
throw InitException() << "DipoleMatching::doinit(): Choice of shower phase space cannot be handled by the matching";
}
}
// need to fo this after for consistency checks
ShowerApproximation::doinit();
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<DipoleMatching,Herwig::ShowerApproximation>
describeHerwigDipoleMatching("Herwig::DipoleMatching", "HwDipoleMatching.so HwShower.so");
void DipoleMatching::Init() {
static ClassDocumentation<DipoleMatching> documentation
("DipoleMatching implements NLO matching with the dipole shower.");
static Reference<DipoleMatching,ShowerHandler> interfaceShowerHandler
("ShowerHandler",
"The dipole shower handler object to use.",
&DipoleMatching::theShowerHandler, false, false, true, true, false);
interfaceShowerHandler.rank(-1);
}
diff --git a/MatrixElement/Matchbox/Matching/DipoleMatching.h b/MatrixElement/Matchbox/Matching/DipoleMatching.h
--- a/MatrixElement/Matchbox/Matching/DipoleMatching.h
+++ b/MatrixElement/Matchbox/Matching/DipoleMatching.h
@@ -1,140 +1,125 @@
// -*- C++ -*-
//
// DipoleMatching.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_DipoleMatching_H
#define Herwig_DipoleMatching_H
//
// This is the declaration of the DipoleMatching class.
//
#include "Herwig/Shower/ShowerHandler.h"
#include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief DipoleMatching implements NLO matching with the dipole shower.
*
*/
class DipoleMatching: public Herwig::ShowerApproximation {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- DipoleMatching();
-
- /**
- * The destructor.
- */
- virtual ~DipoleMatching();
- //@}
-
-public:
-
/**
* Return the shower approximation to the real emission cross
* section for the given pair of Born and real emission
* configurations.
*/
virtual CrossSection dSigHatDR() const;
/**
* Return the shower approximation splitting kernel for the given
* pair of Born and real emission configurations in units of the
* Born center of mass energy squared, and including a weight to
* project onto the splitting given by the dipole used.
*/
virtual double me2() 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).
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
//@}
private:
/**
* The shower handler to be used
*/
Ptr<ShowerHandler>::ptr theShowerHandler;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DipoleMatching & operator=(const DipoleMatching &) = delete;
};
}
#endif /* Herwig_DipoleMatching_H */
diff --git a/MatrixElement/Matchbox/Matching/HardScaleProfile.cc b/MatrixElement/Matchbox/Matching/HardScaleProfile.cc
--- a/MatrixElement/Matchbox/Matching/HardScaleProfile.cc
+++ b/MatrixElement/Matchbox/Matching/HardScaleProfile.cc
@@ -1,134 +1,132 @@
// -*- C++ -*-
//
// HardScaleProfile.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 HardScaleProfile class.
//
#include "HardScaleProfile.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
HardScaleProfile::HardScaleProfile()
: theFixedHardScale(ZERO), theProfileRho(0.3),
theProfileType(resummation) {}
-HardScaleProfile::~HardScaleProfile() {}
-
IBPtr HardScaleProfile::clone() const {
return new_ptr(*this);
}
IBPtr HardScaleProfile::fullclone() const {
return new_ptr(*this);
}
double HardScaleProfile::hardScaleProfile(Energy hard, Energy soft) const {
if ( theFixedHardScale > ZERO )
hard = theFixedHardScale;
double x = soft/hard;
if ( theProfileType == theta ) {
return x <= 1. ? 1.0 : 0.0;
}
if ( theProfileType == resummation ) {
if ( x > 1. ) {
return 0.;
} else if ( x <= 1. && x > 1. - theProfileRho ) {
return sqr(1.-x)/(2.*sqr(theProfileRho));
} else if ( x <= 1. - theProfileRho &&
x > 1. - 2.*theProfileRho ) {
return 1. - sqr(1.-2.*theProfileRho-x)/(2.*sqr(theProfileRho));
} else {
return 1.;
}
}
if ( theProfileType == hfact ) {
return 1./(1.+x);
}
return 1.;
}
bool HardScaleProfile::unrestrictedPhasespace() const {
if ( theProfileType == theta ||
theProfileType == resummation ) {
return false;
}
return true;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void HardScaleProfile::persistentOutput(PersistentOStream & os) const {
os << ounit(theFixedHardScale,GeV) << theProfileRho << theProfileType;
}
void HardScaleProfile::persistentInput(PersistentIStream & is, int) {
is >> iunit(theFixedHardScale,GeV) >> theProfileRho >> theProfileType;
}
// *** 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<HardScaleProfile,Interfaced>
describeHerwigHardScaleProfile("Herwig::HardScaleProfile", "Herwig.so");
void HardScaleProfile::Init() {
static ClassDocumentation<HardScaleProfile> documentation
("HardScaleProfile implements profile scales.");
static Parameter<HardScaleProfile,Energy> interfaceFixedHardScale
("FixedHardScale",
"A fixed hard scale to be used instead of the process specific choice.",
&HardScaleProfile::theFixedHardScale, GeV, ZERO, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<HardScaleProfile,double> interfaceProfileRho
("ProfileRho",
"The profile width parameter",
&HardScaleProfile::theProfileRho, 0.3, 0.0, 1.0,
false, false, Interface::limited);
static Switch<HardScaleProfile,int> interfaceProfileType
("ProfileType",
"The type of profile to use.",
&HardScaleProfile::theProfileType, resummation, false, false);
static SwitchOption interfaceProfileTypeTheta
(interfaceProfileType,
"Theta",
"Use a hard cutoff.",
theta);
static SwitchOption interfaceProfileTypeResummation
(interfaceProfileType,
"Resummation",
"Use the resummation profile with quadratic interpolation.",
resummation);
static SwitchOption interfaceProfileTypeHFact
(interfaceProfileType,
"HFact",
"Use the hfact profile.",
hfact);
}
diff --git a/MatrixElement/Matchbox/Matching/HardScaleProfile.h b/MatrixElement/Matchbox/Matching/HardScaleProfile.h
--- a/MatrixElement/Matchbox/Matching/HardScaleProfile.h
+++ b/MatrixElement/Matchbox/Matching/HardScaleProfile.h
@@ -1,150 +1,142 @@
// -*- C++ -*-
//
// HardScaleProfile.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_HardScaleProfile_H
#define Herwig_HardScaleProfile_H
//
// This is the declaration of the HardScaleProfile class.
//
#include "ThePEG/Interface/Interfaced.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief HardScaleProfile is the base class for profile scales. A few
* standard choices are provided by this implementation.
*
*/
class HardScaleProfile: public Interfaced {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
HardScaleProfile();
- /**
- * The destructor.
- */
- virtual ~HardScaleProfile();
- //@}
-
public:
/**
* Return a scale profile towards the hard scale
*/
virtual double hardScaleProfile(Energy hard, Energy soft) const;
/**
* Return true, if this hard scale profile requires an unrestricted
* radiation phase space.
*/
virtual bool unrestrictedPhasespace() 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).
protected:
/**
* Enumerate the possible profiles
*/
enum ProfileTypes {
theta = 0,
/** hard theta cut */
resummation = 1,
/** `resummation' profile with quadratic interpolation */
hfact = 2
/** hfact profile */
};
/**
* A fixed hard scale to be used instead of the hard scale decided
* for the process in question.
*/
Energy theFixedHardScale;
/**
* A dimensionless width parameter setting the smearing size
* relative to the hard scale; this may have different
* interpretations depending on the profile type chosen.
*/
double theProfileRho;
/**
* The profile type to be used
*/
int theProfileType;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
HardScaleProfile & operator=(const HardScaleProfile &) = delete;
};
}
#endif /* Herwig_HardScaleProfile_H */
diff --git a/MatrixElement/Matchbox/Matching/MEMatching.cc b/MatrixElement/Matchbox/Matching/MEMatching.cc
--- a/MatrixElement/Matchbox/Matching/MEMatching.cc
+++ b/MatrixElement/Matchbox/Matching/MEMatching.cc
@@ -1,152 +1,150 @@
// -*- C++ -*-
//
// MEMatching.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MEMatching class.
//
#include "MEMatching.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Handlers/StdXCombGroup.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
using namespace Herwig;
MEMatching::MEMatching()
: theTruncatedShower(false) {}
-MEMatching::~MEMatching() {}
-
IBPtr MEMatching::clone() const {
return new_ptr(*this);
}
IBPtr MEMatching::fullclone() const {
return new_ptr(*this);
}
CrossSection MEMatching::dSigHatDR() const {
// need to ensure the partner dipoles all got their xcombs set
// for a safe evaluation of channelweight
Ptr<StdXCombGroup>::tcptr grp =
dynamic_ptr_cast<Ptr<StdXCombGroup>::tcptr>(realCXComb());
assert(grp);
for ( vector<StdXCombPtr>::const_iterator dep = grp->dependent().begin();
dep != grp->dependent().end(); ++dep ) {
(**dep).matrixElement()->setXComb(*dep);
}
double xme2 = dipole()->realEmissionME()->me2();
xme2 *= channelWeight();
xme2 /=
pow(dipole()->realEmissionME()->lastXComb().lastAlphaS(),
(double)(dipole()->realEmissionME()->orderInAlphaS()));
xme2 *=
pow(dipole()->underlyingBornME()->lastXComb().lastAlphaS(),
(double)(dipole()->underlyingBornME()->orderInAlphaS()));
double bornPDF = bornPDFWeight(dipole()->underlyingBornME()->lastScale());
if ( bornPDF == 0.0 )
return ZERO;
xme2 *= bornPDF;
if ( profileScales() )
xme2 *= profileScales()->hardScaleProfile(dipole()->showerHardScale(),dipole()->lastPt());
return
sqr(hbarc) *
realXComb()->jacobian() *
subtractionScaleWeight() *
xme2 /
(2. * realXComb()->lastSHat());
}
double MEMatching::me2() const {
double bme2 = bornXComb()->matrixElement()->me2();
bme2 /=
pow(dipole()->underlyingBornME()->lastXComb().lastAlphaS(),
(double)(dipole()->underlyingBornME()->orderInAlphaS()));
double rme2 = dipole()->realEmissionME()->me2();
rme2 /=
pow(dipole()->realEmissionME()->lastXComb().lastAlphaS(),
(double)(dipole()->realEmissionME()->orderInAlphaS()));
rme2 *=
pow(bornXComb()->lastSHat()/realXComb()->lastSHat(),
realCXComb()->mePartonData().size()-4.);
if ( profileScales() )
rme2 *= profileScales()->hardScaleProfile(dipole()->showerHardScale(),dipole()->lastPt());
return
channelWeight() * (rme2/bme2) *
(bornXComb()->lastSHat()/realXComb()->lastSHat()) *
splittingScaleWeight();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MEMatching::persistentOutput(PersistentOStream & os) const {
os << theTruncatedShower;
}
void MEMatching::persistentInput(PersistentIStream & is, int) {
is >> theTruncatedShower;
}
// *** 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<MEMatching,Herwig::ShowerApproximation>
describeHerwigMEMatching("Herwig::MEMatching", "Herwig.so");
void MEMatching::Init() {
static ClassDocumentation<MEMatching> documentation
("MEMatching implements NLO matching with matrix element correction (aka Powheg).");
static Switch<MEMatching,bool> interfaceTruncatedShower
("TruncatedShower",
"Include a truncated qtilde shower",
&MEMatching::theTruncatedShower, false, false, false);
static SwitchOption interfaceTruncatedShowerYes
(interfaceTruncatedShower,
"Yes",
"",
true);
static SwitchOption interfaceTruncatedShowerNo
(interfaceTruncatedShower,
"No",
"",
false);
}
diff --git a/MatrixElement/Matchbox/Matching/MEMatching.h b/MatrixElement/Matchbox/Matching/MEMatching.h
--- a/MatrixElement/Matchbox/Matching/MEMatching.h
+++ b/MatrixElement/Matchbox/Matching/MEMatching.h
@@ -1,147 +1,139 @@
// -*- C++ -*-
//
// MEMatching.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MEMatching_H
#define Herwig_MEMatching_H
//
// This is the declaration of the MEMatching class.
//
#include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MEMatching implements NLO matching with matrix element correction (aka Powheg).
*
*/
class MEMatching: public Herwig::ShowerApproximation {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MEMatching();
- /**
- * The destructor.
- */
- virtual ~MEMatching();
- //@}
-
public:
/**
* Return true, if this shower approximation will require a
* splitting generator
*/
virtual bool needsSplittingGenerator() const { return true; }
/**
* Return true, if this shower approximation will require
* H events
*/
virtual bool hasHEvents() const { return restrictPhasespace() || profileScales(); }
/**
* Return true, if this shower approximation will require
* a truncated parton shower
*/
virtual bool needsTruncatedShower() const { return theTruncatedShower; }
public:
/**
* Return the shower approximation to the real emission cross
* section for the given pair of Born and real emission
* configurations.
*/
virtual CrossSection dSigHatDR() const;
/**
* Return the shower approximation splitting kernel for the given
* pair of Born and real emission configurations in units of the
* Born center of mass energy squared, and including a weight to
* project onto the splitting given by the dipole used.
*/
virtual double me2() 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.
*/
MEMatching & operator=(const MEMatching &) = delete;
/**
* True, if a truncated parton shower should be generated
*/
bool theTruncatedShower;
};
}
#endif /* Herwig_MEMatching_H */
diff --git a/MatrixElement/Matchbox/Matching/QTildeMatching.cc b/MatrixElement/Matchbox/Matching/QTildeMatching.cc
--- a/MatrixElement/Matchbox/Matching/QTildeMatching.cc
+++ b/MatrixElement/Matchbox/Matching/QTildeMatching.cc
@@ -1,538 +1,536 @@
// -*- C++ -*-
//
// QTildeMatching.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the QTildeMatching class.
//
#include "QTildeMatching.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h"
#include "Herwig/Shower/QTilde/Kinematics/KinematicHelpers.h"
using namespace Herwig;
QTildeMatching::QTildeMatching()
: theCorrectForXZMismatch(true) {}
-QTildeMatching::~QTildeMatching() {}
-
IBPtr QTildeMatching::clone() const {
return new_ptr(*this);
}
IBPtr QTildeMatching::fullclone() const {
return new_ptr(*this);
}
void QTildeMatching::checkCutoff() {
if ( showerTildeKinematics() ) {
showerTildeKinematics()->
prepare(realCXComb(),bornCXComb());
showerTildeKinematics()->dipole(dipole());
showerTildeKinematics()->getShowerVariables();
}
}
void QTildeMatching::getShowerVariables() {
// already filled from checkCutoff in this case
if ( showerTildeKinematics() )
return;
// get the shower variables
calculateShowerVariables();
// check for the cutoff
dipole()->isAboveCutoff(isAboveCutoff());
// get the hard scale
dipole()->showerHardScale(hardScale());
// check for phase space
dipole()->isInShowerPhasespace(isInShowerPhasespace());
}
bool QTildeMatching::isInShowerPhasespace() const {
Energy qtildeHard = ZERO;
Energy qtilde = dipole()->showerScale();
assert(!dipole()->showerParameters().empty());
double z = dipole()->showerParameters()[0];
// FF
if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() > 1 ) {
qtildeHard =
theQTildeFinder->
calculateFinalFinalScales(bornCXComb()->meMomenta()[dipole()->bornEmitter()],
bornCXComb()->meMomenta()[dipole()->bornSpectator()]).first;
}
// FI
if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() < 2 ) {
qtildeHard =
theQTildeFinder->
calculateInitialFinalScales(bornCXComb()->meMomenta()[dipole()->bornSpectator()],
bornCXComb()->meMomenta()[dipole()->bornEmitter()],false).second;
}
// IF
if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() > 1 ) {
qtildeHard =
theQTildeFinder->
calculateInitialFinalScales(bornCXComb()->meMomenta()[dipole()->bornEmitter()],
bornCXComb()->meMomenta()[dipole()->bornSpectator()],false).first;
if ( z < (dipole()->bornEmitter() == 0 ? bornCXComb()->lastX1() : bornCXComb()->lastX2()) )
return false;
}
// II
if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() < 2 ) {
qtildeHard =
theQTildeFinder->
calculateInitialInitialScales(bornCXComb()->meMomenta()[dipole()->bornEmitter()],
bornCXComb()->meMomenta()[dipole()->bornSpectator()]).first;
if ( z < (dipole()->bornEmitter() == 0 ? bornCXComb()->lastX1() : bornCXComb()->lastX2()) )
return false;
}
Energy2 pt2 = ZERO;
const vector<Energy> & masses = theQTildeSudakov->virtualMasses({{
bornCXComb()->mePartonData()[dipole()->bornEmitter() ],
realCXComb()->mePartonData()[dipole()->realEmitter() ],
realCXComb()->mePartonData()[dipole()->realEmission()]
}});
const Energy2 m22 = sqr(masses[2]);
if ( dipole()->bornEmitter() > 1 ) {
const Energy2 m02 = sqr(masses[0]);
const Energy2 m12 = sqr(masses[1]);
pt2 = QTildeKinematics::pT2_FSR(sqr(qtilde),z,m02,m12,m22,m12,m22);
}
else {
pt2 = QTildeKinematics::pT2_ISR(sqr(qtilde),z,m22);
}
if ( pt2 < max(theQTildeSudakov->pT2min(),sqr(safeCut()) ))
return false;
bool hardVeto = restrictPhasespace() && sqrt(pt2) >= dipole()->showerHardScale();
return qtilde <= qtildeHard && !hardVeto;
}
bool QTildeMatching::isAboveCutoff() const {
Energy qtilde = dipole()->showerScale();
assert(!dipole()->showerParameters().empty());
double z = dipole()->showerParameters()[0];
const vector<Energy> & masses = theQTildeSudakov->virtualMasses({{
bornCXComb()->mePartonData()[dipole()->bornEmitter() ],
realCXComb()->mePartonData()[dipole()->realEmitter() ],
realCXComb()->mePartonData()[dipole()->realEmission()]
}});
const Energy2 m22 = sqr(masses[2]);
if ( dipole()->bornEmitter() > 1 ) {
const Energy2 m02 = sqr(masses[0]);
const Energy2 m12 = sqr(masses[1]);
const Energy2 pt2 = QTildeKinematics::pT2_FSR(sqr(qtilde),z,m02,m12,m22,m12,m22);
return pt2 >= max(theQTildeSudakov->pT2min(),sqr(safeCut()));
}
else {
const Energy2 pt2 = QTildeKinematics::pT2_ISR(sqr(qtilde),z,m22);
return pt2 >= max(theQTildeSudakov->pT2min(),sqr(safeCut()));
}
return false;
}
CrossSection QTildeMatching::dSigHatDR() const {
assert(!dipole()->showerParameters().empty());
pair<Energy2,double> vars =
make_pair(sqr(dipole()->showerScale()),
dipole()->showerParameters()[0]);
pair<int,int> ij(dipole()->bornEmitter(),
dipole()->bornSpectator());
double ccme2 =
dipole()->underlyingBornME()->largeNColourCorrelatedME2(ij,theLargeNBasis);
if(ccme2==0.)return 0.*nanobarn;
double lnme2=dipole()->underlyingBornME()->largeNME2(theLargeNBasis);
if(lnme2==0){
generator()->log() <<"\nQTildeMatching: ";
generator()->log() <<"\n largeNME2 is ZERO, while largeNColourCorrelatedME2 is not ZERO." ;
generator()->log() <<"\n This is too seriuos.\n" ;
generator()->log() << Exception::runerror;
}
ccme2 *=
dipole()->underlyingBornME()->me2() /lnme2;
Energy2 prop = ZERO;
if ( dipole()->bornEmitter() > 1 ) {
prop =
(realCXComb()->meMomenta()[dipole()->realEmitter()] +
realCXComb()->meMomenta()[dipole()->realEmission()]).m2()
- bornCXComb()->meMomenta()[dipole()->bornEmitter()].m2();
} else {
prop =
2.*vars.second*(realCXComb()->meMomenta()[dipole()->realEmitter()]*
realCXComb()->meMomenta()[dipole()->realEmission()]);
}
// note alphas included downstream from subtractionScaleWeight()
double xme2 = -8.*Constants::pi*ccme2*splitFn(vars)*realXComb()->lastSHat()/prop;
xme2 *=
pow(realCXComb()->lastSHat() / bornCXComb()->lastSHat(),
bornCXComb()->mePartonData().size()-4.);
double bornPDF = bornPDFWeight(dipole()->underlyingBornME()->lastScale());
if ( bornPDF == 0.0 )
return ZERO;
xme2 *= bornPDF;
xme2 *= dipole()->realEmissionME()->finalStateSymmetry() /
dipole()->underlyingBornME()->finalStateSymmetry();
// take care of mismatch between z and x as we are approaching the
// hard phase space boundary
// TODO get rid of this useless scale option business and simplify PDF handling in here
if ( dipole()->bornEmitter() < 2 && theCorrectForXZMismatch ) {
Energy2 emissionScale = ZERO;
if ( emissionScaleInSubtraction() == showerScale ) {
emissionScale = showerFactorizationScale();
} else if ( emissionScaleInSubtraction() == realScale ) {
emissionScale = dipole()->realEmissionME()->lastScale();
} else if ( emissionScaleInSubtraction() == bornScale ) {
emissionScale = dipole()->underlyingBornME()->lastScale();
}
double xzMismatch =
dipole()->subtractionParameters()[0] / dipole()->showerParameters()[0];
double realCorrectedPDF =
dipole()->bornEmitter() == 0 ?
dipole()->realEmissionME()->pdf1(emissionScale,theExtrapolationX,
xzMismatch) :
dipole()->realEmissionME()->pdf2(emissionScale,theExtrapolationX,
xzMismatch);
double realPDF =
dipole()->bornEmitter() == 0 ?
dipole()->realEmissionME()->pdf1(emissionScale,theExtrapolationX,1.0) :
dipole()->realEmissionME()->pdf2(emissionScale,theExtrapolationX,1.0);
if ( realPDF == 0.0 || realCorrectedPDF == 0.0 )
return ZERO;
xme2 *= realCorrectedPDF / realPDF;
}
Energy qtilde = sqrt(vars.first);
double z = vars.second;
Energy2 pt2 = ZERO;
const vector<Energy> & masses = theQTildeSudakov->virtualMasses({{
bornCXComb()->mePartonData()[dipole()->bornEmitter() ],
realCXComb()->mePartonData()[dipole()->realEmitter() ],
realCXComb()->mePartonData()[dipole()->realEmission()]
}});
const Energy2 m22 = sqr(masses[2]);
if ( dipole()->bornEmitter() > 1 ) {
const Energy2 m02 = sqr(masses[0]);
const Energy2 m12 = sqr(masses[1]);
pt2 = QTildeKinematics::pT2_FSR(sqr(qtilde),z,m02,m12,m22,m12,m22);
}
else {
pt2 = QTildeKinematics::pT2_ISR(sqr(qtilde),z,m22);
}
assert(pt2 >= ZERO);
if ( profileScales() )
xme2 *= profileScales()->hardScaleProfile(dipole()->showerHardScale(),sqrt(pt2));
CrossSection res =
sqr(hbarc) *
realXComb()->jacobian() *
subtractionScaleWeight() *
xme2 /
(2. * realXComb()->lastSHat());
return res;
}
double QTildeMatching::me2() const {
throw Exception() << "QTildeMatching::me2(): Not intented to use. Disable the ShowerApproximationGenerator."
<< Exception::runerror;
return 0.;
}
void QTildeMatching::calculateShowerVariables() const {
Lorentz5Momentum n;
Energy2 Q2 = ZERO;
const Lorentz5Momentum& pb = bornCXComb()->meMomenta()[dipole()->bornEmitter()];
const Lorentz5Momentum& pc = bornCXComb()->meMomenta()[dipole()->bornSpectator()];
if ( dipole()->bornEmitter() > 1 ) {
Q2 = (pb+pc).m2();
} else {
Q2 = -(pb-pc).m2();
}
if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() > 1 ) {
double b = sqr(bornCXComb()->meMomenta()[dipole()->bornEmitter()].m())/Q2;
double c = sqr(bornCXComb()->meMomenta()[dipole()->bornSpectator()].m())/Q2;
double lambda = sqrt(1.+sqr(b)+sqr(c)-2.*b-2.*c-2.*b*c);
n = (1.-0.5*(1.-b+c-lambda))*pc - 0.5*(1.-b+c-lambda)*pb;
}
if ( dipole()->bornEmitter() > 1 && dipole()->bornSpectator() < 2 ) {
n = bornCXComb()->meMomenta()[dipole()->bornSpectator()];
}
if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() > 1 ) {
double c = sqr(bornCXComb()->meMomenta()[dipole()->bornSpectator()].m())/Q2;
n = (1.+c)*pc - c*pb;
}
if ( dipole()->bornEmitter() < 2 && dipole()->bornSpectator() < 2 ) {
n = bornCXComb()->meMomenta()[dipole()->bornSpectator()];
}
// the light-cone condition is numerically not very stable, so we
// explicitly push it on the light-cone here
n.setMass(ZERO);
n.rescaleEnergy();
double z = 0.0;
if ( dipole()->bornEmitter() > 1 ) {
z = 1. -
(n*realCXComb()->meMomenta()[dipole()->realEmission()])/
(n*bornCXComb()->meMomenta()[dipole()->bornEmitter()]);
} else {
z = 1. -
(n*realCXComb()->meMomenta()[dipole()->realEmission()])/
(n*realCXComb()->meMomenta()[dipole()->realEmitter()]);
}
// allow small violations (numerical inaccuracies)
if ( z <= 0 && z >= -1e-6 ) {
z = std::numeric_limits<double>::epsilon();
} else if ( z >= 1 && z <= 1+1e-6 ) {
z = 1-std::numeric_limits<double>::epsilon();
}
Energy2 qtilde2 = ZERO;
Energy2 q2 = ZERO;
if ( dipole()->bornEmitter() > 1 ) {
q2 =
(realCXComb()->meMomenta()[dipole()->realEmitter()] + realCXComb()->meMomenta()[dipole()->realEmission()]).m2();
qtilde2 = (q2 - bornCXComb()->meMomenta()[dipole()->bornEmitter()].m2())/(z*(1.-z));
} else {
q2 =
-(realCXComb()->meMomenta()[dipole()->realEmitter()] - realCXComb()->meMomenta()[dipole()->realEmission()]).m2();
qtilde2 = (q2 + bornCXComb()->meMomenta()[dipole()->bornEmitter()].m2())/(1.-z);
}
if ( qtilde2 < ZERO ) {
qtilde2 = ZERO;
}
assert(qtilde2 >= ZERO && z > 0.0 && z < 1.0);
dipole()->showerScale(sqrt(qtilde2));
dipole()->showerParameters().resize(1);
dipole()->showerParameters()[0] = z;
}
double QTildeMatching::splitFn(const pair<Energy2,double>& vars) const {
const Energy2& qtilde2 = vars.first;
const double z = vars.second;
double Nc = SM().Nc();
// final state branching
if ( dipole()->bornEmitter() > 1 ) {
// final state quark quark branching
if ( abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) < 7 ) {
Energy m = bornCXComb()->mePartonData()[dipole()->bornEmitter()]->hardProcessMass();
return
((sqr(Nc)-1.)/(2.*Nc))*(1+sqr(z)-2.*sqr(m)/(z*qtilde2))/(1.-z);
}
// final state gluon branching
if ( bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id() == ParticleID::g ) {
if ( realCXComb()->mePartonData()[dipole()->realEmission()]->id() == ParticleID::g ) {
// ATTENTION the factor 2 here is intentional as it cancels to the 1/2
// stemming from the large-N colour correlator
return 2.*Nc*(z/(1.-z)+(1.-z)/z+z*(1.-z));
}
if ( abs(realCXComb()->mePartonData()[dipole()->realEmission()]->id()) < 7 ) {
Energy m = realCXComb()->mePartonData()[dipole()->realEmission()]->hardProcessMass();
return (1./2.)*(1.-2.*z*(1.-z)+2.*sqr(m)/(z*(1.-z)*qtilde2));
}
}
// final state squark branching
if ((abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) > 1000000 &&
abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) < 1000007) ||
(abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) > 2000000 &&
abs(bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id()) < 2000007)){
Energy m = bornCXComb()->mePartonData()[dipole()->bornEmitter()]->hardProcessMass();
return ((sqr(Nc)-1.)/Nc)*(z-sqr(m)/(z*qtilde2))/(1.-z);
}
// final state gluino branching
if (bornCXComb()->mePartonData()[dipole()->bornEmitter()]->id() == 1000021){
Energy m = bornCXComb()->mePartonData()[dipole()->bornEmitter()]->hardProcessMass();
return Nc*(1.+sqr(z)-2.*sqr(m)/(z*qtilde2))/(1.-z);
}
}
// initial state branching
if ( dipole()->bornEmitter() < 2 ) {
// g/g
if ( realCXComb()->mePartonData()[dipole()->realEmitter()]->id() == ParticleID::g &&
realCXComb()->mePartonData()[dipole()->realEmission()]->id() == ParticleID::g ) {
// see above for factor of 2
return 2.*Nc*(z/(1.-z)+(1.-z)/z+z*(1.-z));
}
// q/q
if ( abs(realCXComb()->mePartonData()[dipole()->realEmitter()]->id()) < 7 &&
realCXComb()->mePartonData()[dipole()->realEmission()]->id() == ParticleID::g ) {
return
((sqr(Nc)-1.)/(2.*Nc))*(1+sqr(z))/(1.-z);
}
// g/q
if ( realCXComb()->mePartonData()[dipole()->realEmitter()]->id() == ParticleID::g &&
abs(realCXComb()->mePartonData()[dipole()->realEmission()]->id()) < 7 ) {
return (1./2.)*(1.-2.*z*(1.-z));
}
// q/g
if ( abs(realCXComb()->mePartonData()[dipole()->realEmitter()]->id()) < 7 &&
abs(realCXComb()->mePartonData()[dipole()->realEmission()]->id()) < 7 ) {
return
((sqr(Nc)-1.)/(2.*Nc))*(1+sqr(1.-z))/z;
}
}
return 0.0;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void QTildeMatching::doinit() {
assert(theShowerHandler && theQTildeFinder && theQTildeSudakov);
theShowerHandler->init();
theQTildeFinder->init();
theQTildeSudakov->init();
hardScaleFactor(theShowerHandler->hardScaleFactor());
factorizationScaleFactor(theShowerHandler->factorizationScaleFactor());
renormalizationScaleFactor(theShowerHandler->renormalizationScaleFactor());
profileScales(theShowerHandler->profileScales());
restrictPhasespace(theShowerHandler->restrictPhasespace());
hardScaleIsMuF(theShowerHandler->hardScaleIsMuF());
ShowerApproximation::doinit();
}
void QTildeMatching::doinitrun() {
assert(theShowerHandler && theQTildeFinder && theQTildeSudakov);
theShowerHandler->initrun();
theQTildeFinder->initrun();
theQTildeSudakov->initrun();
ShowerApproximation::doinitrun();
}
void QTildeMatching::persistentOutput(PersistentOStream & os) const {
os << theQTildeFinder << theQTildeSudakov
<< theShowerHandler << theCorrectForXZMismatch;
}
void QTildeMatching::persistentInput(PersistentIStream & is, int) {
is >> theQTildeFinder >> theQTildeSudakov
>> theShowerHandler >> theCorrectForXZMismatch;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<QTildeMatching,Herwig::ShowerApproximation>
describeHerwigQTildeMatching("Herwig::QTildeMatching", "HwShower.so HwQTildeMatching.so");
void QTildeMatching::Init() {
static ClassDocumentation<QTildeMatching> documentation
("QTildeMatching implements NLO matching with the default shower.");
static Reference<QTildeMatching,PartnerFinder> interfaceQTildeFinder
("QTildeFinder",
"Set the partner finder to calculate hard scales.",
&QTildeMatching::theQTildeFinder, false, false, true, false, false);
interfaceQTildeFinder.rank(-1);
static Reference<QTildeMatching,SudakovFormFactor> interfaceQTildeSudakov
("QTildeSudakov",
"Set the partner finder to calculate hard scales.",
&QTildeMatching::theQTildeSudakov, false, false, true, false, false);
interfaceQTildeSudakov.rank(-1);
static Reference<QTildeMatching,ShowerHandler> interfaceShowerHandler
("ShowerHandler",
"The QTilde shower handler to use.",
&QTildeMatching::theShowerHandler, false, false, true, true, false);
interfaceShowerHandler.rank(-1);
static Switch<QTildeMatching,bool> interfaceCorrectForXZMismatch
("CorrectForXZMismatch",
"Correct for x/z mismatch near hard phase space boundary.",
&QTildeMatching::theCorrectForXZMismatch, true, false, false);
static SwitchOption interfaceCorrectForXZMismatchYes
(interfaceCorrectForXZMismatch,
"Yes",
"Include the correction factor.",
true);
static SwitchOption interfaceCorrectForXZMismatchNo
(interfaceCorrectForXZMismatch,
"No",
"Do not include the correction factor.",
false);
interfaceCorrectForXZMismatch.rank(-1);
}
diff --git a/MatrixElement/Matchbox/Matching/QTildeMatching.h b/MatrixElement/Matchbox/Matching/QTildeMatching.h
--- a/MatrixElement/Matchbox/Matching/QTildeMatching.h
+++ b/MatrixElement/Matchbox/Matching/QTildeMatching.h
@@ -1,201 +1,193 @@
// -*- C++ -*-
//
// QTildeMatching.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_QTildeMatching_H
#define Herwig_QTildeMatching_H
//
// This is the declaration of the QTildeMatching class.
//
#include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
#include "Herwig/Shower/ShowerHandler.h"
#include "Herwig/Shower/QTilde/Base/PartnerFinder.h"
#include "Herwig/Shower/QTilde/SplittingFunctions/SudakovFormFactor.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief QTildeMatching implements NLO matching with the default shower.
*
*/
class QTildeMatching: public Herwig::ShowerApproximation {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
QTildeMatching();
- /**
- * The destructor.
- */
- virtual ~QTildeMatching();
- //@}
-
public:
/**
* Return the shower approximation to the real emission cross
* section for the given pair of Born and real emission
* configurations.
*/
virtual CrossSection dSigHatDR() const;
/**
* Return the shower approximation splitting kernel for the given
* pair of Born and real emission configurations in units of the
* Born center of mass energy squared, and including a weight to
* project onto the splitting given by the dipole used.
*/
virtual double me2() const;
/**
* Determine if the configuration is below or above the cutoff.
*/
virtual void checkCutoff();
/**
* Determine all kinematic variables which are not provided by the
* dipole kinematics; store all shower variables in the respective
* dipole object for later use.
*/
virtual void getShowerVariables();
protected:
/**
* Return true, if the shower was able to generate an emission
* leading from the given Born to the given real emission process.
*/
virtual bool isInShowerPhasespace() const;
/**
* Return true, if the shower emission leading from the given Born
* to the given real emission process would have been generated
* above the shower's infrared cutoff.
*/
virtual bool isAboveCutoff() const;
/**
* Calculate qtilde^2 and z for the splitting considered
*/
void calculateShowerVariables() const;
/**
* Return the splitting function as a function of the kinematic
* variables
*/
double splitFn(const pair<Energy2,double>&) 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).
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 assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
QTildeMatching & operator=(const QTildeMatching &) = delete;
/**
* The shower handler to be used
*/
Ptr<ShowerHandler>::ptr theShowerHandler;
/**
* The qtilde partner finder for calculating the hard scales
*/
Ptr<PartnerFinder>::ptr theQTildeFinder;
/**
* The qtilde Sudakov to access the cutoff
*/
Ptr<SudakovFormFactor>::ptr theQTildeSudakov;
/**
* True, if PDF weight should be corrected for z/x mismatch at the
* hard phase space boundary
*/
bool theCorrectForXZMismatch;
};
}
#endif /* Herwig_QTildeMatching_H */
diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximation.cc b/MatrixElement/Matchbox/Matching/ShowerApproximation.cc
--- a/MatrixElement/Matchbox/Matching/ShowerApproximation.cc
+++ b/MatrixElement/Matchbox/Matching/ShowerApproximation.cc
@@ -1,718 +1,716 @@
// -*- C++ -*-
//
// ShowerApproximation.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the ShowerApproximation class.
//
#include "ShowerApproximation.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h"
using namespace Herwig;
ShowerApproximation::ShowerApproximation()
: HandlerBase(),
theExtrapolationX(1.0), theBelowCutoff(false),
theFFPtCut(1.0*GeV), theFFScreeningScale(ZERO),
theFIPtCut(1.0*GeV), theFIScreeningScale(ZERO),
theIIPtCut(1.0*GeV), theIIScreeningScale(ZERO),
theSafeCut(0.0*GeV),
theRestrictPhasespace(true), theHardScaleFactor(1.0),
theRenormalizationScaleFactor(1.0), theFactorizationScaleFactor(1.0),
theRealEmissionScaleInSubtraction(showerScale),
theBornScaleInSubtraction(showerScale),
theEmissionScaleInSubtraction(showerScale),
theRealEmissionScaleInSplitting(showerScale),
theBornScaleInSplitting(showerScale),
theEmissionScaleInSplitting(showerScale),
theRenormalizationScaleFreeze(1.*GeV),
theFactorizationScaleFreeze(1.*GeV),
maxPtIsMuF(false), theOpenZ(true) {}
-ShowerApproximation::~ShowerApproximation() {}
-
void ShowerApproximation::setLargeNBasis() {
assert(dipole()->realEmissionME()->matchboxAmplitude());
if ( !dipole()->realEmissionME()->matchboxAmplitude()->treeAmplitudes() )
return;
if ( !theLargeNBasis ) {
if ( !dipole()->realEmissionME()->matchboxAmplitude()->colourBasis() )
throw Exception() << "ShowerApproximation::setLargeNBasis(): Expecting a colour basis object."
<< Exception::runerror;
theLargeNBasis =
dipole()->realEmissionME()->matchboxAmplitude()->colourBasis()->cloneMe();
theLargeNBasis->clear();
theLargeNBasis->doLargeN();
}
}
void ShowerApproximation::setDipole(Ptr<SubtractionDipole>::tptr dip) {
theDipole = dip;
setLargeNBasis();
}
Ptr<SubtractionDipole>::tptr ShowerApproximation::dipole() const { return theDipole; }
Ptr<TildeKinematics>::tptr
ShowerApproximation::showerTildeKinematics() const {
return Ptr<TildeKinematics>::tptr();
}
Ptr<InvertedTildeKinematics>::tptr
ShowerApproximation::showerInvertedTildeKinematics() const {
return Ptr<InvertedTildeKinematics>::tptr();
}
void ShowerApproximation::checkCutoff() {
assert(!showerTildeKinematics());
}
void ShowerApproximation::getShowerVariables() {
// check for the cutoff
dipole()->isAboveCutoff(isAboveCutoff());
// get the hard scale
dipole()->showerHardScale(hardScale());
// set the shower scale and variables for completeness
dipole()->showerScale(dipole()->lastPt());
dipole()->showerParameters().resize(1);
dipole()->showerParameters()[0] = dipole()->lastZ();
// check for phase space
dipole()->isInShowerPhasespace(isInShowerPhasespace());
}
bool ShowerApproximation::isAboveCutoff() const {
if ( dipole()->bornEmitter() > 1 &&
dipole()->bornSpectator() > 1 ) {
return dipole()->lastPt() >= max(ffPtCut(),safeCut());
} else if ( ( dipole()->bornEmitter() > 1 &&
dipole()->bornSpectator() < 2 ) ||
( dipole()->bornEmitter() < 2 &&
dipole()->bornSpectator() > 1 ) ) {
return dipole()->lastPt() >= max(fiPtCut(),safeCut());
} else {
assert(dipole()->bornEmitter() < 2 &&
dipole()->bornSpectator() < 2);
return dipole()->lastPt() >= max(iiPtCut(),safeCut());
}
return true;
}
Energy ShowerApproximation::hardScale() const {
if ( !maxPtIsMuF ) {
if ( !bornCXComb()->mePartonData()[0]->coloured() &&
!bornCXComb()->mePartonData()[1]->coloured() ) {
Energy maxPt = (bornCXComb()->meMomenta()[0] + bornCXComb()->meMomenta()[1]).m();
maxPt *= hardScaleFactor();
return maxPt;
}
Energy maxPt = generator()->maximumCMEnergy();
vector<Lorentz5Momentum>::const_iterator p =
bornCXComb()->meMomenta().begin() + 2;
cPDVector::const_iterator pp =
bornCXComb()->mePartonData().begin() + 2;
for ( ; p != bornCXComb()->meMomenta().end(); ++p, ++pp )
if ( (**pp).coloured() )
maxPt = min(maxPt,p->mt());
if ( maxPt == generator()->maximumCMEnergy() )
maxPt = (bornCXComb()->meMomenta()[0] + bornCXComb()->meMomenta()[1]).m();
maxPt *= hardScaleFactor();
return maxPt;
} else {
return hardScaleFactor()*sqrt(bornCXComb()->lastShowerScale());
}
}
bool ShowerApproximation::isInShowerPhasespace() const {
if ( !dipole()->isAboveCutoff() )
return false;
if ( !restrictPhasespace() )
return true;
InvertedTildeKinematics& kinematics =
const_cast<InvertedTildeKinematics&>(*dipole()->invertedTildeKinematics());
tcStdXCombPtr tmpreal = kinematics.realXComb();
tcStdXCombPtr tmpborn = kinematics.bornXComb();
Ptr<SubtractionDipole>::tptr tmpdip = kinematics.dipole();
Energy hard = dipole()->showerHardScale();
Energy pt = dipole()->lastPt();
double z = dipole()->lastZ();
pair<double,double> zbounds(0.,1.);
kinematics.dipole(const_ptr_cast<Ptr<SubtractionDipole>::tptr>(theDipole));
kinematics.prepare(realCXComb(),bornCXComb());
if ( pt > hard ) {
kinematics.dipole(tmpdip);
kinematics.prepare(tmpreal,tmpborn);
return false;
}
try {
zbounds = kinematics.zBounds(pt,openZ() ? kinematics.ptMax() : hard);
} catch(...) {
kinematics.dipole(tmpdip);
kinematics.prepare(tmpreal,tmpborn);
throw;
}
kinematics.dipole(tmpdip);
kinematics.prepare(tmpreal,tmpborn);
return z > zbounds.first && z < zbounds.second;
}
Energy2 ShowerApproximation::showerEmissionScale() const {
Energy2 mur = sqr(dipole()->lastPt());
if ( dipole()->bornEmitter() > 1 &&
dipole()->bornSpectator() > 1 ) {
return mur + sqr(ffScreeningScale());
} else if ( ( dipole()->bornEmitter() > 1 &&
dipole()->bornSpectator() < 2 ) ||
( dipole()->bornEmitter() < 2 &&
dipole()->bornSpectator() > 1 ) ) {
return mur + sqr(fiScreeningScale());
} else {
assert(dipole()->bornEmitter() < 2 &&
dipole()->bornSpectator() < 2);
return mur + sqr(iiScreeningScale());
}
return mur;
}
Energy2 ShowerApproximation::bornRenormalizationScale() const {
return
sqr(dipole()->underlyingBornME()->renormalizationScaleFactor()) *
dipole()->underlyingBornME()->renormalizationScale();
}
Energy2 ShowerApproximation::bornFactorizationScale() const {
return
sqr(dipole()->underlyingBornME()->factorizationScaleFactor()) *
dipole()->underlyingBornME()->factorizationScale();
}
Energy2 ShowerApproximation::realRenormalizationScale() const {
return
sqr(dipole()->realEmissionME()->renormalizationScaleFactor()) *
dipole()->realEmissionME()->renormalizationScale();
}
Energy2 ShowerApproximation::realFactorizationScale() const {
return
sqr(dipole()->realEmissionME()->factorizationScaleFactor()) *
dipole()->realEmissionME()->factorizationScale();
}
double ShowerApproximation::bornPDFWeight(Energy2 muf) const {
if ( !bornCXComb()->mePartonData()[0]->coloured() &&
!bornCXComb()->mePartonData()[1]->coloured() )
return 1.;
if ( muf < sqr(theFactorizationScaleFreeze) )
muf = sqr(theFactorizationScaleFreeze);
double pdfweight = 1.;
if ( bornCXComb()->mePartonData()[0]->coloured() &&
dipole()->underlyingBornME()->havePDFWeight1() )
pdfweight *= dipole()->underlyingBornME()->pdf1(muf,theExtrapolationX);
if ( bornCXComb()->mePartonData()[1]->coloured() &&
dipole()->underlyingBornME()->havePDFWeight2() )
pdfweight *= dipole()->underlyingBornME()->pdf2(muf,theExtrapolationX);
return pdfweight;
}
double ShowerApproximation::realPDFWeight(Energy2 muf) const {
if ( !realCXComb()->mePartonData()[0]->coloured() &&
!realCXComb()->mePartonData()[1]->coloured() )
return 1.;
if ( muf < sqr(theFactorizationScaleFreeze) )
muf = sqr(theFactorizationScaleFreeze);
double pdfweight = 1.;
if ( realCXComb()->mePartonData()[0]->coloured() &&
dipole()->realEmissionME()->havePDFWeight1() )
pdfweight *= dipole()->realEmissionME()->pdf1(muf,theExtrapolationX);
if ( realCXComb()->mePartonData()[1]->coloured() &&
dipole()->realEmissionME()->havePDFWeight2() )
pdfweight *= dipole()->realEmissionME()->pdf2(muf,theExtrapolationX);
return pdfweight;
}
double ShowerApproximation::scaleWeight(int rScale, int bScale, int eScale) const {
double emissionAlpha = 1.;
Energy2 emissionScale = ZERO;
Energy2 showerscale = ZERO;
if ( eScale == showerScale || bScale == showerScale || eScale == showerScale ) {
showerscale = showerRenormalizationScale();
if ( showerscale < sqr(theRenormalizationScaleFreeze) )
showerscale = sqr(theFactorizationScaleFreeze);
}
if ( eScale == showerScale ) {
emissionAlpha = SM().alphaS(showerscale);
emissionScale = showerFactorizationScale();
} else if ( eScale == realScale ) {
emissionAlpha = dipole()->realEmissionME()->lastXComb().lastAlphaS();
emissionScale = dipole()->realEmissionME()->lastScale();
} else if ( eScale == bornScale ) {
emissionAlpha = dipole()->underlyingBornME()->lastXComb().lastAlphaS();
emissionScale = dipole()->underlyingBornME()->lastScale();
}
double emissionPDF = realPDFWeight(emissionScale);
double couplingFactor = 1.;
if ( bScale != rScale ) {
double bornAlpha = 1.;
if ( bScale == showerScale ) {
bornAlpha = SM().alphaS(showerscale);
} else if ( bScale == realScale ) {
bornAlpha = dipole()->realEmissionME()->lastXComb().lastAlphaS();
} else if ( bScale == bornScale ) {
bornAlpha = dipole()->underlyingBornME()->lastXComb().lastAlphaS();
}
double realAlpha = 1.;
if ( rScale == showerScale ) {
realAlpha = SM().alphaS(showerscale);
} else if ( rScale == realScale ) {
realAlpha = dipole()->realEmissionME()->lastXComb().lastAlphaS();
} else if ( rScale == bornScale ) {
realAlpha = dipole()->underlyingBornME()->lastXComb().lastAlphaS();
}
couplingFactor *=
pow(realAlpha/bornAlpha,(double)(dipole()->underlyingBornME()->orderInAlphaS()));
}
Energy2 hardScale = ZERO;
if ( bScale == showerScale ) {
hardScale = showerFactorizationScale();
} else if ( bScale == realScale ) {
hardScale = dipole()->realEmissionME()->lastScale();
} else if ( bScale == bornScale ) {
hardScale = dipole()->underlyingBornME()->lastScale();
}
double bornPDF = bornPDFWeight(hardScale);
if ( abs(bornPDF) < 1e-8 )
bornPDF = 0.0;
if ( abs(emissionPDF) < 1e-8 )
emissionPDF = 0.0;
if ( emissionPDF == 0.0 || bornPDF == 0.0 )
return 0.0;
double pdfRatio = emissionPDF/bornPDF;
pdfRatio = min(abs(pdfRatio),100000.);
return
emissionAlpha * pdfRatio * couplingFactor;
}
double ShowerApproximation::channelWeight(int emitter, int emission,
int spectator, int) const {
double cfac = 1.;
double Nc = generator()->standardModel()->Nc();
if (realCXComb()->mePartonData()[emitter]->iColour() == PDT::Colour8){
if (realCXComb()->mePartonData()[emission]->iColour() == PDT::Colour8)
cfac = Nc;
else if ( realCXComb()->mePartonData()[emission]->iColour() == PDT::Colour3 ||
realCXComb()->mePartonData()[emission]->iColour() == PDT::Colour3bar)
cfac = 0.5;
else assert(false);
}
else if ((realCXComb()->mePartonData()[emitter] ->iColour() == PDT::Colour3 ||
realCXComb()->mePartonData()[emitter] ->iColour() == PDT::Colour3bar))
cfac = (sqr(Nc)-1.)/(2.*Nc);
else assert(false);
// do the most simple thing for the time being; needs fixing later
if ( realCXComb()->mePartonData()[emission]->id() == ParticleID::g ) {
Energy2 pipk =
realCXComb()->meMomenta()[emitter] * realCXComb()->meMomenta()[spectator];
Energy2 pipj =
realCXComb()->meMomenta()[emitter] * realCXComb()->meMomenta()[emission];
Energy2 pjpk =
realCXComb()->meMomenta()[emission] * realCXComb()->meMomenta()[spectator];
return cfac *GeV2 * pipk / ( pipj * ( pipj + pjpk ) );
}
return
cfac * GeV2 / (realCXComb()->meMomenta()[emitter] * realCXComb()->meMomenta()[emission]);
}
double ShowerApproximation::channelWeight() const {
double currentChannel = channelWeight(dipole()->realEmitter(),
dipole()->realEmission(),
dipole()->realSpectator(),
dipole()->bornEmitter());
if ( currentChannel == 0. )
return 0.;
double sum = 0.;
for ( vector<Ptr<SubtractionDipole>::tptr>::const_iterator dip =
dipole()->partnerDipoles().begin();
dip != dipole()->partnerDipoles().end(); ++dip )
sum += channelWeight((**dip).realEmitter(),
(**dip).realEmission(),
(**dip).realSpectator(),
(**dip).bornEmitter());
assert(sum > 0.0);
return currentChannel / sum;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void ShowerApproximation::doinit() {
if ( profileScales() ) {
if ( profileScales()->unrestrictedPhasespace() &&
restrictPhasespace() ) {
generator()->log()
<< "ShowerApproximation warning: The scale profile chosen requires an unrestricted phase space,\n"
<< "however, the phase space was set to be restricted. Will switch to unrestricted phase space.\n"
<< flush;
restrictPhasespace(false);
}
}
HandlerBase::doinit();
}
void ShowerApproximation::persistentOutput(PersistentOStream & os) const {
os << theLargeNBasis
<< theBornXComb << theRealXComb << theTildeXCombs << theDipole << theBelowCutoff
<< ounit(theFFPtCut,GeV) << ounit(theFFScreeningScale,GeV)
<< ounit(theFIPtCut,GeV) << ounit(theFIScreeningScale,GeV)
<< ounit(theIIPtCut,GeV) << ounit(theIIScreeningScale,GeV)
<< ounit(theSafeCut,GeV)
<< theRestrictPhasespace << theHardScaleFactor
<< theRenormalizationScaleFactor << theFactorizationScaleFactor
<< theExtrapolationX
<< theRealEmissionScaleInSubtraction << theBornScaleInSubtraction
<< theEmissionScaleInSubtraction << theRealEmissionScaleInSplitting
<< theBornScaleInSplitting << theEmissionScaleInSplitting
<< ounit(theRenormalizationScaleFreeze,GeV)
<< ounit(theFactorizationScaleFreeze,GeV) << maxPtIsMuF
<< theHardScaleProfile << theOpenZ;
}
void ShowerApproximation::persistentInput(PersistentIStream & is, int) {
is >> theLargeNBasis
>> theBornXComb >> theRealXComb >> theTildeXCombs >> theDipole >> theBelowCutoff
>> iunit(theFFPtCut,GeV) >> iunit(theFFScreeningScale,GeV)
>> iunit(theFIPtCut,GeV) >> iunit(theFIScreeningScale,GeV)
>> iunit(theIIPtCut,GeV) >> iunit(theIIScreeningScale,GeV)
>> iunit(theSafeCut,GeV)
>> theRestrictPhasespace >> theHardScaleFactor
>> theRenormalizationScaleFactor >> theFactorizationScaleFactor
>> theExtrapolationX
>> theRealEmissionScaleInSubtraction >> theBornScaleInSubtraction
>> theEmissionScaleInSubtraction >> theRealEmissionScaleInSplitting
>> theBornScaleInSplitting >> theEmissionScaleInSplitting
>> iunit(theRenormalizationScaleFreeze,GeV)
>> iunit(theFactorizationScaleFreeze,GeV) >> maxPtIsMuF
>> theHardScaleProfile >> theOpenZ;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeAbstractClass<ShowerApproximation,HandlerBase>
describeHerwigShowerApproximation("Herwig::ShowerApproximation", "Herwig.so");
void ShowerApproximation::Init() {
static ClassDocumentation<ShowerApproximation> documentation
("ShowerApproximation describes the shower emission to be used "
"in NLO matching.");
static Parameter<ShowerApproximation,Energy> interfaceFFPtCut
("FFPtCut",
"Set the pt infrared cutoff",
&ShowerApproximation::theFFPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceFIPtCut
("FIPtCut",
"Set the pt infrared cutoff",
&ShowerApproximation::theFIPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceIIPtCut
("IIPtCut",
"Set the pt infrared cutoff",
&ShowerApproximation::theIIPtCut, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceSafeCut
("SafeCut",
"Set the enhanced infrared cutoff for the Matching.",
&ShowerApproximation::theSafeCut, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceFFScreeningScale
("FFScreeningScale",
"Set the screening scale",
&ShowerApproximation::theFFScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceFIScreeningScale
("FIScreeningScale",
"Set the screening scale",
&ShowerApproximation::theFIScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,Energy> interfaceIIScreeningScale
("IIScreeningScale",
"Set the screening scale",
&ShowerApproximation::theIIScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Switch<ShowerApproximation,bool> interfaceRestrictPhasespace
("RestrictPhasespace",
"Switch on or off phasespace restrictions",
&ShowerApproximation::theRestrictPhasespace, true, false, false);
static SwitchOption interfaceRestrictPhasespaceYes
(interfaceRestrictPhasespace,
"Yes",
"Perform phasespace restrictions",
true);
static SwitchOption interfaceRestrictPhasespaceNo
(interfaceRestrictPhasespace,
"No",
"Do not perform phasespace restrictions",
false);
static Parameter<ShowerApproximation,double> interfaceHardScaleFactor
("HardScaleFactor",
"The hard scale factor.",
&ShowerApproximation::theHardScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,double> interfaceRenormalizationScaleFactor
("RenormalizationScaleFactor",
"The hard scale factor.",
&ShowerApproximation::theRenormalizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,double> interfaceFactorizationScaleFactor
("FactorizationScaleFactor",
"The hard scale factor.",
&ShowerApproximation::theFactorizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximation,double> interfaceExtrapolationX
("ExtrapolationX",
"The x from which on extrapolation should be performed.",
&ShowerApproximation::theExtrapolationX, 1.0, 0.0, 1.0,
false, false, Interface::limited);
static Switch<ShowerApproximation,int> interfaceRealEmissionScaleInSubtraction
("RealEmissionScaleInSubtraction",
"Set the scale choice for the real emission cross section in the matching subtraction.",
&ShowerApproximation::theRealEmissionScaleInSubtraction, showerScale, false, false);
static SwitchOption interfaceRealEmissionScaleInSubtractionRealScale
(interfaceRealEmissionScaleInSubtraction,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceRealEmissionScaleInSubtractionBornScale
(interfaceRealEmissionScaleInSubtraction,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceRealEmissionScaleInSubtractionShowerScale
(interfaceRealEmissionScaleInSubtraction,
"ShowerScale",
"Use the shower scale",
showerScale);
interfaceRealEmissionScaleInSubtraction.rank(-1);
static Switch<ShowerApproximation,int> interfaceBornScaleInSubtraction
("BornScaleInSubtraction",
"Set the scale choice for the Born cross section in the matching subtraction.",
&ShowerApproximation::theBornScaleInSubtraction, showerScale, false, false);
static SwitchOption interfaceBornScaleInSubtractionRealScale
(interfaceBornScaleInSubtraction,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceBornScaleInSubtractionBornScale
(interfaceBornScaleInSubtraction,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceBornScaleInSubtractionShowerScale
(interfaceBornScaleInSubtraction,
"ShowerScale",
"Use the shower scale",
showerScale);
interfaceBornScaleInSubtraction.rank(-1);
static Switch<ShowerApproximation,int> interfaceEmissionScaleInSubtraction
("EmissionScaleInSubtraction",
"Set the scale choice for the emission in the matching subtraction.",
&ShowerApproximation::theEmissionScaleInSubtraction, showerScale, false, false);
static SwitchOption interfaceEmissionScaleInSubtractionRealScale
(interfaceEmissionScaleInSubtraction,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceEmissionScaleInSubtractionEmissionScale
(interfaceEmissionScaleInSubtraction,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceEmissionScaleInSubtractionShowerScale
(interfaceEmissionScaleInSubtraction,
"ShowerScale",
"Use the shower scale",
showerScale);
interfaceEmissionScaleInSubtraction.rank(-1);
static Switch<ShowerApproximation,int> interfaceRealEmissionScaleInSplitting
("RealEmissionScaleInSplitting",
"Set the scale choice for the real emission cross section in the splitting.",
&ShowerApproximation::theRealEmissionScaleInSplitting, showerScale, false, false);
static SwitchOption interfaceRealEmissionScaleInSplittingRealScale
(interfaceRealEmissionScaleInSplitting,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceRealEmissionScaleInSplittingBornScale
(interfaceRealEmissionScaleInSplitting,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceRealEmissionScaleInSplittingShowerScale
(interfaceRealEmissionScaleInSplitting,
"ShowerScale",
"Use the shower scale",
showerScale);
interfaceRealEmissionScaleInSplitting.rank(-1);
static Switch<ShowerApproximation,int> interfaceBornScaleInSplitting
("BornScaleInSplitting",
"Set the scale choice for the Born cross section in the splitting.",
&ShowerApproximation::theBornScaleInSplitting, showerScale, false, false);
static SwitchOption interfaceBornScaleInSplittingRealScale
(interfaceBornScaleInSplitting,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceBornScaleInSplittingBornScale
(interfaceBornScaleInSplitting,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceBornScaleInSplittingShowerScale
(interfaceBornScaleInSplitting,
"ShowerScale",
"Use the shower scale",
showerScale);
interfaceBornScaleInSplitting.rank(-1);
static Switch<ShowerApproximation,int> interfaceEmissionScaleInSplitting
("EmissionScaleInSplitting",
"Set the scale choice for the emission in the splitting.",
&ShowerApproximation::theEmissionScaleInSplitting, showerScale, false, false);
static SwitchOption interfaceEmissionScaleInSplittingRealScale
(interfaceEmissionScaleInSplitting,
"RealScale",
"Use the real emission scale.",
realScale);
static SwitchOption interfaceEmissionScaleInSplittingEmissionScale
(interfaceEmissionScaleInSplitting,
"BornScale",
"Use the Born scale.",
bornScale);
static SwitchOption interfaceEmissionScaleInSplittingShowerScale
(interfaceEmissionScaleInSplitting,
"ShowerScale",
"Use the shower scale",
showerScale);
interfaceEmissionScaleInSplitting.rank(-1);
static Parameter<ShowerApproximation,Energy> interfaceRenormalizationScaleFreeze
("RenormalizationScaleFreeze",
"The freezing scale for the renormalization scale.",
&ShowerApproximation::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
interfaceRenormalizationScaleFreeze.rank(-1);
static Parameter<ShowerApproximation,Energy> interfaceFactorizationScaleFreeze
("FactorizationScaleFreeze",
"The freezing scale for the factorization scale.",
&ShowerApproximation::theFactorizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
interfaceFactorizationScaleFreeze.rank(-1);
static Reference<ShowerApproximation,HardScaleProfile> interfaceHardScaleProfile
("HardScaleProfile",
"The hard scale profile to use.",
&ShowerApproximation::theHardScaleProfile, false, false, true, true, false);
static Reference<ShowerApproximation,ColourBasis> interfaceLargeNBasis
("LargeNBasis",
"Set the large-N colour basis implementation.",
&ShowerApproximation::theLargeNBasis, false, false, true, true, false);
interfaceLargeNBasis.rank(-1);
static Switch<ShowerApproximation,bool> interfaceMaxPtIsMuF
("MaxPtIsMuF",
"",
&ShowerApproximation::maxPtIsMuF, false, false, false);
static SwitchOption interfaceMaxPtIsMuFYes
(interfaceMaxPtIsMuF,
"Yes",
"",
true);
static SwitchOption interfaceMaxPtIsMuFNo
(interfaceMaxPtIsMuF,
"No",
"",
false);
}
diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximation.h b/MatrixElement/Matchbox/Matching/ShowerApproximation.h
--- a/MatrixElement/Matchbox/Matching/ShowerApproximation.h
+++ b/MatrixElement/Matchbox/Matching/ShowerApproximation.h
@@ -1,691 +1,683 @@
// -*- C++ -*-
//
// ShowerApproximation.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_ShowerApproximation_H
#define Herwig_ShowerApproximation_H
//
// This is the declaration of the ShowerApproximation class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.fh"
#include "Herwig/MatrixElement/Matchbox/Utility/ColourBasis.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.fh"
#include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.fh"
#include "HardScaleProfile.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief ShowerApproximation describes the shower emission to be used
* in NLO matching.
*
*/
class ShowerApproximation: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
ShowerApproximation();
- /**
- * The destructor.
- */
- virtual ~ShowerApproximation();
- //@}
-
public:
/**
* Return true, if this shower approximation will require a
* splitting generator
*/
virtual bool needsSplittingGenerator() const { return false; }
/**
* Return true, if this shower approximation will require
* H events
*/
virtual bool hasHEvents() const { return true; }
/**
* Return true, if this shower approximation will require tilde
* XCombs for the real phase space point generated
*/
virtual bool needsTildeXCombs() const { return false; }
/**
* Return true, if this shower approximation will require
* a truncated parton shower
*/
virtual bool needsTruncatedShower() const { return false; }
/**
* Return the tilde kinematics object returning the shower
* kinematics parametrization if different from the nominal dipole
* mappings.
*/
virtual Ptr<TildeKinematics>::tptr showerTildeKinematics() const;
/**
* Return the tilde kinematics object returning the shower
* kinematics parametrization if different from the nominal dipole
* mappings.
*/
virtual Ptr<InvertedTildeKinematics>::tptr showerInvertedTildeKinematics() const;
public:
/**
* Set the XComb object describing the Born process
*/
void setBornXComb(tStdXCombPtr xc) { theBornXComb = xc; }
/**
* Return the XComb object describing the Born process
*/
tStdXCombPtr bornXComb() const { return theBornXComb; }
/**
* Return the XComb object describing the Born process
*/
tcStdXCombPtr bornCXComb() const { return theBornXComb; }
/**
* Set the XComb object describing the real emission process
*/
void setRealXComb(tStdXCombPtr xc) { theRealXComb = xc; }
/**
* Return the XComb object describing the real emission process
*/
tStdXCombPtr realXComb() const { return theRealXComb; }
/**
* Return the XComb object describing the real emission process
*/
tcStdXCombPtr realCXComb() const { return theRealXComb; }
/**
* Set the tilde xcomb objects associated to the real xcomb
*/
void setTildeXCombs(const vector<StdXCombPtr>& xc) { theTildeXCombs = xc; }
/**
* Return the tilde xcomb objects associated to the real xcomb
*/
const vector<StdXCombPtr>& tildeXCombs() const { return theTildeXCombs; }
/**
* Set the dipole in charge for the emission
*/
void setDipole(Ptr<SubtractionDipole>::tptr);
/**
* Return the dipole in charge for the emission
*/
Ptr<SubtractionDipole>::tptr dipole() const;
/**
* Return true, if this matching is capable of spin correlations.
*/
virtual bool hasSpinCorrelations() const { return false; }
public:
/**
* Return true if one of the recently encountered configutations was
* below the infrared cutoff.
*/
bool belowCutoff() const { return theBelowCutoff; }
/**
* Indicate that one of the recently encountered configutations was
* below the infrared cutoff.
*/
void wasBelowCutoff() { theBelowCutoff = true; }
/**
* Reset the below cutoff flag.
*/
void resetBelowCutoff() { theBelowCutoff = false; }
/**
* Return the pt cut to be applied for final-final dipoles.
*/
Energy ffPtCut() const { return theFFPtCut; }
/**
* Return the pt cut to be applied for final-initial dipoles.
*/
Energy fiPtCut() const { return theFIPtCut; }
/**
* Return the pt cut to be applied for initial-initial dipoles.
*/
Energy iiPtCut() const { return theIIPtCut; }
/**
* Return the pt cut to be applied for initial-initial dipoles.
*/
Energy safeCut() const { return theSafeCut;}
/**
* Return the screening scale to be applied for final-final dipoles.
*/
Energy ffScreeningScale() const { return theFFScreeningScale; }
/**
* Return the screening scale to be applied for final-initial dipoles.
*/
Energy fiScreeningScale() const { return theFIScreeningScale; }
/**
* Return the screening scale to be applied for initial-initial dipoles.
*/
Energy iiScreeningScale() const { return theIIScreeningScale; }
/**
* Return the shower renormalization scale
*/
virtual Energy2 showerEmissionScale() const;
/**
* Return the shower renormalization scale
*/
Energy2 showerRenormalizationScale() const {
return sqr(renormalizationScaleFactor())*showerEmissionScale();
}
/**
* Return the shower factorization scale
*/
Energy2 showerFactorizationScale() const {
return sqr(factorizationScaleFactor())*showerEmissionScale();
}
/**
* Return the Born renormalization scale
*/
Energy2 bornRenormalizationScale() const;
/**
* Return the Born factorization scale
*/
Energy2 bornFactorizationScale() const;
/**
* Return the real emission renormalization scale
*/
Energy2 realRenormalizationScale() const;
/**
* Return the real emission factorization scale
*/
Energy2 realFactorizationScale() const;
/**
* Enumerate possible scale choices
*/
enum ScaleChoices {
bornScale = 0,
/** Use the born scales */
realScale = 1,
/** Use the real scales */
showerScale = 2
/** Use the shower scales */
};
/**
* Return the scale choice in the real emission cross section to be
* used in the matching subtraction.
*/
int realEmissionScaleInSubtraction() const { return theRealEmissionScaleInSubtraction; }
/**
* Return the scale choice in the born cross section to be
* used in the matching subtraction.
*/
int bornScaleInSubtraction() const { return theBornScaleInSubtraction; }
/**
* Return the scale choice in the emission contribution to be
* used in the matching subtraction.
*/
int emissionScaleInSubtraction() const { return theEmissionScaleInSubtraction; }
/**
* Return the scale choice in the real emission cross section to be
* used in the splitting.
*/
int realEmissionScaleInSplitting() const { return theRealEmissionScaleInSplitting; }
/**
* Return the scale choice in the born cross section to be
* used in the splitting.
*/
int bornScaleInSplitting() const { return theBornScaleInSplitting; }
/**
* Return the scale choice in the emission contribution to be
* used in the splitting.
*/
int emissionScaleInSplitting() const { return theEmissionScaleInSplitting; }
/**
* Return the scale weight
*/
double scaleWeight(int rScale, int bScale, int eScale) const;
/**
* Return the scale weight for the matching subtraction
*/
double subtractionScaleWeight() const {
return scaleWeight(realEmissionScaleInSubtraction(),
bornScaleInSubtraction(),
emissionScaleInSubtraction());
}
/**
* Return the scale weight for the splitting
*/
double splittingScaleWeight() const {
return scaleWeight(realEmissionScaleInSplitting(),
bornScaleInSplitting(),
emissionScaleInSplitting());
}
public:
/**
* Return true, if the phase space restrictions of the dipole shower should
* be applied.
*/
bool restrictPhasespace() const { return theRestrictPhasespace; }
/**
* Indicate that the phase space restrictions of the dipole shower should
* be applied.
*/
void restrictPhasespace(bool yes) { theRestrictPhasespace = yes; }
/**
* Return profile scales
*/
Ptr<HardScaleProfile>::tptr profileScales() const { return theHardScaleProfile; }
/**
* Set profile scales
*/
void profileScales(Ptr<HardScaleProfile>::ptr prof) { theHardScaleProfile = prof; }
/**
* Return true if maximum pt should be deduced from the factorization scale
*/
bool hardScaleIsMuF() const { return maxPtIsMuF; }
/**
* Indicate that maximum pt should be deduced from the factorization scale
*/
void hardScaleIsMuF(bool yes) { maxPtIsMuF = yes; }
/**
* Return the scale factor for the hard scale
*/
double hardScaleFactor() const { return theHardScaleFactor; }
/**
* Set the scale factor for the hard scale
*/
void hardScaleFactor(double f) { theHardScaleFactor = f; }
/**
* Get the factorization scale factor
*/
double factorizationScaleFactor() const { return theFactorizationScaleFactor; }
/**
* Get the renormalization scale factor
*/
double renormalizationScaleFactor() const { return theRenormalizationScaleFactor; }
/**
* Set the factorization scale factor
*/
void factorizationScaleFactor(double f) { theFactorizationScaleFactor = f; }
/**
* Set the renormalization scale factor
*/
void renormalizationScaleFactor(double f) { theRenormalizationScaleFactor = f; }
/**
* Determine if the configuration is below or above the cutoff.
*/
virtual void checkCutoff();
/**
* Determine all kinematic variables which are not provided by the
* dipole kinematics; store all shower variables in the respective
* dipole object for later use.
*/
virtual void getShowerVariables();
/**
* Return the shower approximation to the real emission cross
* section for the given pair of Born and real emission
* configurations.
*/
virtual CrossSection dSigHatDR() const = 0;
/**
* Return the shower approximation splitting kernel for the given
* pair of Born and real emission configurations in units of the
* Born center of mass energy squared, and including a weight to
* project onto the splitting given by the dipole used.
*/
virtual double me2() const = 0;
/**
* Return the Born PDF weight
*/
double bornPDFWeight(Energy2 muF) const;
/**
* Return the real emission PDF weight
*/
double realPDFWeight(Energy2 muF) const;
protected:
/**
* Return true, if the shower was able to generate an emission
* leading from the given Born to the given real emission process.
*/
virtual bool isInShowerPhasespace() const;
/**
* Return true, if the shower emission leading from the given Born
* to the given real emission process would have been generated
* above the shower's infrared cutoff.
*/
virtual bool isAboveCutoff() const;
/**
* Return the relevant hard scale
*/
virtual Energy hardScale() const;
/**
* Use the maximum available phase space for the momentum fraction
*/
void useOpenZ(bool yes) { theOpenZ = yes; }
/**
* Return true if the maximum available phase space should be used
* for the momentum fraction
*/
bool openZ() const { return theOpenZ; }
public:
/**
* Generate a weight for the given dipole channel
*/
virtual double channelWeight(int emitter, int emission,
int spectator, int bemitter) const;
/**
* Generate a normalized weight taking into account all channels
*/
virtual double channelWeight() 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();
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
public:
/**
* A large-N colour basis to be used when reproducing the shower
* kernels.
*/
Ptr<ColourBasis>::tptr largeNBasis() const { return theLargeNBasis; }
protected:
/**
* A large-N colour basis to be used when reproducing the shower
* kernels.
*/
Ptr<ColourBasis>::ptr theLargeNBasis;
/**
* Set the large-N basis
*/
void setLargeNBasis();
/**
* The x value from which on we extrapolate PDFs for numerically stable ratios.
*/
double theExtrapolationX;
private:
/**
* The XComb object describing the Born process
*/
tStdXCombPtr theBornXComb;
/**
* The XComb object describing the real emission process
*/
tStdXCombPtr theRealXComb;
/**
* The tilde xcomb objects associated to the real xcomb
*/
vector<StdXCombPtr> theTildeXCombs;
/**
* The dipole in charge for the emission
*/
Ptr<SubtractionDipole>::tptr theDipole;
/**
* True if one of the recently encountered configutations was below
* the infrared cutoff.
*/
bool theBelowCutoff;
/**
* The pt cut to be applied for final-final dipoles.
*/
Energy theFFPtCut;
/**
* An optional screening scale for final-final dipoles; see
* DipoleSplittingKernel
*/
Energy theFFScreeningScale;
/**
* The pt cut to be applied for final-initial dipoles.
*/
Energy theFIPtCut;
/**
* An optional screening scale for final-initial dipoles; see
* DipoleSplittingKernel
*/
Energy theFIScreeningScale;
/**
* The pt cut to be applied for initial-initial dipoles.
*/
Energy theIIPtCut;
/**
* An optional screening scale for initial-initial dipoles; see
* DipoleSplittingKernel
*/
Energy theIIScreeningScale;
/**
* The cut to be applied as an enhanced shower cutoff.
*/
Energy theSafeCut;
/**
* True, if the phase space restrictions of the dipole shower should
* be applied.
*/
bool theRestrictPhasespace;
/**
* The scale factor for the hard scale
*/
double theHardScaleFactor;
/**
* The scale factor for the renormalization scale
*/
double theRenormalizationScaleFactor;
/**
* The scale factor for the factorization scale
*/
double theFactorizationScaleFactor;
/**
* The scale choice in the real emission cross section to be
* used in the matching subtraction.
*/
int theRealEmissionScaleInSubtraction;
/**
* The scale choice in the born cross section to be
* used in the matching subtraction.
*/
int theBornScaleInSubtraction;
/**
* The scale choice in the emission contribution to be
* used in the matching subtraction.
*/
int theEmissionScaleInSubtraction;
/**
* The scale choice in the real emission cross section to be
* used in the splitting.
*/
int theRealEmissionScaleInSplitting;
/**
* The scale choice in the born cross section to be
* used in the splitting.
*/
int theBornScaleInSplitting;
/**
* The scale choice in the emission contribution to be
* used in the splitting.
*/
int theEmissionScaleInSplitting;
/**
* A freezing value for the renormalization scale
*/
Energy theRenormalizationScaleFreeze;
/**
* A freezing value for the factorization scale
*/
Energy theFactorizationScaleFreeze;
/**
* True if maximum pt should be deduced from the factorization scale
*/
bool maxPtIsMuF;
/**
* The profile scales
*/
Ptr<HardScaleProfile>::ptr theHardScaleProfile;
/**
* Use the maximum available phase space for the momentum fraction
*/
bool theOpenZ;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
ShowerApproximation & operator=(const ShowerApproximation &) = delete;
};
}
#endif /* Herwig_ShowerApproximation_H */
diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc
--- a/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc
+++ b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.cc
@@ -1,527 +1,525 @@
// -*- C++ -*-
//
// ShowerApproximationGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the ShowerApproximationGenerator class.
//
#include <config.h>
#include "ShowerApproximationGenerator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/PDT/EnumParticles.h"
#include "ThePEG/PDF/PartonExtractor.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
ShowerApproximationGenerator::ShowerApproximationGenerator()
: thePresamplingPoints(2000), theMaxTry(100000), theFreezeGrid(500000),
theDoCompensate(false) {}
-ShowerApproximationGenerator::~ShowerApproximationGenerator() {}
-
double ShowerApproximationGenerator::generateFraction(tcPDPtr pd, double r, double xmin) const {
if ( pd->coloured() || pd->id() == ParticleID::gamma ) {
return pow(xmin,r);
}
double x0 = 1.e-5;
return 1. + x0 - x0*pow((1.+x0)/x0,r);
}
double ShowerApproximationGenerator::invertFraction(tcPDPtr pd, double x, double xmin) const {
if ( pd->coloured() || pd->id() == ParticleID::gamma ) {
return log(x)/log(xmin);
}
double x0 = 1.e-5;
return log((1.-x+x0)/x0)/log((1.+x0)/x0);
}
bool ShowerApproximationGenerator::prepare(bool didproject) {
tSubProPtr oldSub = lastIncomingXComb->subProcess();
tcStdXCombPtr cIncomingXC = lastIncomingXComb;
bool hasFractions =
thePhasespace->haveX1X2() ||
cIncomingXC->mePartonData().size() == 3;
theLastMomenta.resize(cIncomingXC->mePartonData().size());
if ( !hasFractions )
theLastRandomNumbers.resize(thePhasespace->nDim(cIncomingXC->mePartonData()) + 2);
else
theLastRandomNumbers.resize(thePhasespace->nDim(cIncomingXC->mePartonData()));
if ( !hasFractions ) {
double x1 =
oldSub->incoming().first->momentum().plus() /
lastIncomingXComb->lastParticles().first->momentum().plus();
theLastRandomNumbers[0] = invertFraction(oldSub->incoming().first->dataPtr(),x1,
lastIncomingXComb->cuts()->x1Min());
double x2 =
oldSub->incoming().second->momentum().minus() /
lastIncomingXComb->lastParticles().second->momentum().minus();
theLastRandomNumbers[1] = invertFraction(oldSub->incoming().second->dataPtr(),x2,
lastIncomingXComb->cuts()->x2Min());
}
theLastMomenta = cIncomingXC->meMomenta();
theLastPartons.first =
oldSub->incoming().first->data().produceParticle(oldSub->incoming().first->momentum());
theLastPartons.second =
oldSub->incoming().second->data().produceParticle(oldSub->incoming().second->momentum());
thePhasespace->setXComb(lastIncomingXComb);
// this is a brute force fix for private ticket #241 ; only done to get fixed
// for the release but will need to be looked at in more detail later on by
// cleaning up the XCombs for these cases
if ( theLastMomenta.size() == 3 && didproject ) {
// boost them where they belong so invertKinematics is doing something sensible
Boost toLab = (lastIncomingXComb->lastPartons().first->momentum() +
lastIncomingXComb->lastPartons().second->momentum()).boostVector();
for ( int i = 0; i < 3; ++i )
theLastMomenta[i].boost(toLab);
}
thePhasespace->invertKinematics(theLastMomenta,
!hasFractions ? &theLastRandomNumbers[2] : &theLastRandomNumbers[0]);
theLastBornXComb->clean();
theLastBornXComb->fill(lastIncomingXComb->lastParticles(),theLastPartons,
theLastMomenta,theLastRandomNumbers);
if ( !theLastBornXComb->cuts()->initSubProcess(theLastBornXComb->lastSHat(),
theLastBornXComb->lastY(),
theLastBornXComb->mirror()) )
return false;
theLastBornME->setXComb(theLastBornXComb);
if ( !theLastBornME->generateKinematics(!hasFractions ? &theLastRandomNumbers[2] : &theLastRandomNumbers[0]) )
return false;
CrossSection bornXS = theLastBornME->dSigHatDR();
if ( bornXS == ZERO )
return false;
return true;
}
bool ShowerApproximationGenerator::generate(const vector<double>& r) {
theLastBornXComb->clean();
bool hasFractions =
thePhasespace->haveX1X2() ||
theLastBornXComb->mePartonData().size() == 3;
if ( !hasFractions ) {
double x = generateFraction(theLastPartons.first->dataPtr(),r[0],
lastIncomingXComb->cuts()->x1Min());
Energy Q = lastIncomingXComb->lastParticles().first->momentum().plus();
Energy mass = theLastPartons.first->dataPtr()->mass();
double xi = (sqr(x*Q) - sqr(mass))/(sqr(Q)*x);
Lorentz5Momentum p1(ZERO,ZERO,xi*Q/2.);
p1.setMass(mass); p1.rescaleEnergy();
theLastPartons.first->set5Momentum(p1);
x = generateFraction(theLastPartons.second->dataPtr(),r[1],
lastIncomingXComb->cuts()->x2Min());
Q = lastIncomingXComb->lastParticles().second->momentum().minus();
mass = theLastPartons.second->dataPtr()->mass();
xi = (sqr(x*Q) - sqr(mass))/(sqr(Q)*x);
Lorentz5Momentum p2(ZERO,ZERO,-xi*Q/2.);
p2.setMass(mass); p2.rescaleEnergy();
theLastPartons.second->set5Momentum(p2);
} else {
theLastBornME->setXComb(theLastBornXComb);
theLastBornXComb->lastParticles(lastIncomingXComb->lastParticles());
theLastBornXComb->lastP1P2(make_pair(0.0, 0.0));
theLastBornXComb->lastS(lastIncomingXComb->lastS());
if ( !theLastBornME->generateKinematics(&r[0]) )
return false;
theLastPartons.first->set5Momentum(theLastBornME->lastMEMomenta()[0]);
theLastPartons.second->set5Momentum(theLastBornME->lastMEMomenta()[1]);
}
theLastPresamplingMomenta.resize(theLastMomenta.size());
Boost toCMS =
(theLastPartons.first->momentum() +
theLastPartons.second->momentum()).findBoostToCM();
theLastPresamplingMomenta[0] = theLastPartons.first->momentum();
if ( !hasFractions )
theLastPresamplingMomenta[0].boost(toCMS);
theLastPresamplingMomenta[1] = theLastPartons.second->momentum();
if ( !hasFractions )
theLastPresamplingMomenta[1].boost(toCMS);
if ( hasFractions ) {
for ( size_t k = 2; k < theLastBornME->lastMEMomenta().size(); ++k )
theLastPresamplingMomenta[k] = theLastBornME->lastMEMomenta()[k];
}
theLastBornXComb->fill(lastIncomingXComb->lastParticles(),theLastPartons,
theLastPresamplingMomenta,r);
if ( !theLastBornXComb->cuts()->initSubProcess(theLastBornXComb->lastSHat(),
theLastBornXComb->lastY(),
theLastBornXComb->mirror()) )
return false;
if ( !hasFractions ) {
theLastBornME->setXComb(theLastBornXComb);
if ( !theLastBornME->generateKinematics(&r[2]) )
return false;
}
CrossSection bornXS = theLastBornME->dSigHatDR();
if ( bornXS == ZERO )
return false;
return true;
}
void ShowerApproximationGenerator::restore() {
theLastBornXComb->clean();
bool hasFractions =
thePhasespace->haveX1X2() ||
theLastBornXComb->mePartonData().size() == 3;
if ( !hasFractions ) {
tSubProPtr oldSub = lastIncomingXComb->subProcess();
theLastPartons.first->set5Momentum(oldSub->incoming().first->momentum());
theLastPartons.second->set5Momentum(oldSub->incoming().second->momentum());
} else {
theLastBornME->setXComb(theLastBornXComb);
theLastBornXComb->lastParticles(lastIncomingXComb->lastParticles());
theLastBornXComb->lastP1P2(make_pair(0.0, 0.0));
theLastBornXComb->lastS(lastIncomingXComb->lastS());
theLastBornME->generateKinematics(&theLastRandomNumbers[0]);
theLastPartons.first->set5Momentum(theLastBornME->lastMEMomenta()[0]);
theLastPartons.second->set5Momentum(theLastBornME->lastMEMomenta()[1]);
}
theLastBornXComb->fill(lastIncomingXComb->lastParticles(),theLastPartons,
theLastMomenta,theLastRandomNumbers);
if ( !hasFractions ) {
theLastBornME->setXComb(theLastBornXComb);
theLastBornME->generateKinematics(&theLastRandomNumbers[2]);
}
theLastBornME->dSigHatDR();
}
void ShowerApproximationGenerator::
handle(EventHandler & eh, const tPVector &,
const Hint &) {
MatchboxFactory::currentFactory()->setHardTreeEmitter(-1);
MatchboxFactory::currentFactory()->setHardTreeSpectator(-1);
MatchboxFactory::currentFactory()->setHardTreeSubprocess(SubProPtr());
lastIncomingXComb = dynamic_ptr_cast<tStdXCombPtr>(eh.lastXCombPtr());
if ( !lastIncomingXComb )
throw Exception() << "ShowerApproximationGenerator::handle(): Expecting a standard event handler."
<< Exception::runerror;
bool didproject = false;
if ( lastIncomingXComb->lastProjector() ) {
lastIncomingXComb = lastIncomingXComb->lastProjector();
didproject = true;
}
const StandardXComb& xc = *lastIncomingXComb;
map<cPDVector,set<Ptr<ShowerApproximationKernel>::ptr> >::const_iterator
kernelit = theKernelMap.find(xc.mePartonData());
if ( kernelit == theKernelMap.end() ) {
list<MatchboxFactory::SplittingChannel> channels =
MatchboxFactory::currentFactory()->getSplittingChannels(lastIncomingXComb);
set<Ptr<ShowerApproximationKernel>::ptr> newKernels;
for ( list<MatchboxFactory::SplittingChannel>::const_iterator c =
channels.begin(); c != channels.end(); ++c ) {
Ptr<ShowerApproximationKernel>::ptr kernel =
new_ptr(ShowerApproximationKernel());
kernel->setBornXComb(c->bornXComb);
kernel->setRealXComb(c->realXComb);
kernel->setTildeXCombs(c->tildeXCombs);
kernel->setDipole(c->dipole);
kernel->showerApproximation(theShowerApproximation);
kernel->presamplingPoints(thePresamplingPoints);
kernel->maxtry(theMaxTry);
kernel->freezeGrid(theFreezeGrid);
kernel->showerApproximationGenerator(this);
kernel->doCompensate(theDoCompensate);
if ( kernel->dipole()->bornEmitter() > 1 &&
kernel->dipole()->bornSpectator() > 1 ) {
kernel->ptCut(ffPtCut());
} else if ( ( kernel->dipole()->bornEmitter() > 1 &&
kernel->dipole()->bornSpectator() < 2 ) ||
( kernel->dipole()->bornEmitter() < 2 &&
kernel->dipole()->bornSpectator() > 1 ) ) {
kernel->ptCut(fiPtCut());
} else {
assert(kernel->dipole()->bornEmitter() < 2 &&
kernel->dipole()->bornSpectator() < 2);
kernel->ptCut(iiPtCut());
}
newKernels.insert(kernel);
}
theKernelMap[xc.mePartonData()] = newKernels;
kernelit = theKernelMap.find(xc.mePartonData());
}
if ( kernelit->second.empty() )
return;
const set<Ptr<ShowerApproximationKernel>::ptr>& kernels = kernelit->second;
theLastBornME = (**kernels.begin()).dipole()->underlyingBornME();
if ( theLastBornME->phasespace()->wantCMS() != thePhasespace->wantCMS() ) {
throw Exception() << "Mismatch in centre-of-mass-system requirements of hard matrix element phasespace ("
<< (theLastBornME->phasespace()->wantCMS()?"Yes":"No")
<< ") and shower approximation phasespace ("
<< (thePhasespace->wantCMS()?"Yes":"No") << ")"
<< Exception::abortnow;
}
theLastBornME->phasespace(thePhasespace);
theLastBornXComb = (**kernels.begin()).bornXComb();
if ( !prepare(didproject) )
return;
Energy winnerPt = ZERO;
Ptr<ShowerApproximationKernel>::ptr winnerKernel;
try {
for ( set<Ptr<ShowerApproximationKernel>::ptr>::const_iterator k =
kernels.begin(); k != kernels.end(); ++k ) {
if ( (**k).generate() != 0. && (*k)->dipole()->lastPt() > winnerPt){
winnerKernel = *k;
winnerPt = winnerKernel->dipole()->lastPt();
}
}
} catch(ShowerApproximationKernel::MaxTryException&) {
throw Exception() << "Too many tries needed to generate the matrix element correction in '"
<< name() << "'" << Exception::eventerror;
}
if ( !winnerKernel || winnerPt == ZERO )
return;
//Hardest emission should be this one.
winnerKernel->realXComb()->lastShowerScale(sqr(winnerPt));
winnerKernel->bornXComb()->lastShowerScale(sqr(winnerPt));
lastIncomingXComb->lastShowerScale(sqr(winnerPt));
SubProPtr oldSub = lastIncomingXComb->subProcess();
SubProPtr newSub;
try {
tcDiagPtr bornDiag = lastIncomingXComb->lastDiagram();
tcDiagPtr realDiag =
winnerKernel->dipole()->realEmissionDiagram(bornDiag);
winnerKernel->realXComb()->externalDiagram(realDiag);
newSub = winnerKernel->realXComb()->construct();
} catch(Veto&) {
return;
}
if ( !theShowerApproximation->needsTruncatedShower() ){
tParticleSet firstS = oldSub->incoming().first->siblings();
assert(firstS.empty() || firstS.size() == 1);
if ( !firstS.empty() ) {
eh.currentStep()->removeParticle(*firstS.begin());
}
tParticleSet secondS = oldSub->incoming().second->siblings();
assert(secondS.empty() || secondS.size() == 1);
if ( !secondS.empty() ) {
eh.currentStep()->removeParticle(*secondS.begin());
}
// prevent the colliding particles from disappearing
// in the initial state and appearing
// in the final state when we've cut off all their
// (physical) children; only applies to the case
// where we have a parton extractor not build from
// noPDF, so check wether the incoming particle
// doesnt equal the incoming parton -- this needs fixing in ThePEG
PPtr dummy = new_ptr(Particle(getParticleData(ParticleID::gamma)));
bool usedDummy = false;
if ( eh.currentStep()->incoming().first != oldSub->incoming().first ) {
eh.currentStep()->addDecayProduct(eh.currentStep()->incoming().first,dummy);
usedDummy = true;
}
if ( eh.currentStep()->incoming().second != oldSub->incoming().second ) {
eh.currentStep()->addDecayProduct(eh.currentStep()->incoming().second,dummy);
usedDummy = true;
}
eh.currentStep()->removeSubProcess(oldSub);
eh.currentStep()->addSubProcess(newSub);
// get rid of the dummy
if ( usedDummy ) {
eh.currentStep()->removeParticle(dummy);
}
eh.select(winnerKernel->realXComb());
winnerKernel->realXComb()->recreatePartonBinInstances(winnerKernel->realXComb()->lastScale());
winnerKernel->realXComb()->refillPartonBinInstances(&(xc.lastRandomNumbers()[0]));
winnerKernel->realXComb()->pExtractor()->constructRemnants(winnerKernel->realXComb()->partonBinInstances(),
newSub, eh.currentStep());
}
else{
MatchboxFactory::currentFactory()->setHardTreeSubprocess(newSub);
MatchboxFactory::currentFactory()->setHardTreeEmitter(winnerKernel->dipole()->bornEmitter());
MatchboxFactory::currentFactory()->setHardTreeSpectator(winnerKernel->dipole()->bornSpectator());
}
}
IBPtr ShowerApproximationGenerator::clone() const {
return new_ptr(*this);
}
IBPtr ShowerApproximationGenerator::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void ShowerApproximationGenerator::persistentOutput(PersistentOStream & os) const {
os << theShowerApproximation << thePhasespace
<< theKernelMap << thePresamplingPoints << theMaxTry << theFreezeGrid
<< lastIncomingXComb << theLastBornME << ounit(theLastMomenta,GeV)
<< ounit(theLastPresamplingMomenta,GeV) << theLastRandomNumbers
<< theLastBornXComb << theLastPartons << theDoCompensate;
}
void ShowerApproximationGenerator::persistentInput(PersistentIStream & is, int) {
is >> theShowerApproximation >> thePhasespace
>> theKernelMap >> thePresamplingPoints >> theMaxTry >> theFreezeGrid
>> lastIncomingXComb >> theLastBornME >> iunit(theLastMomenta,GeV)
>> iunit(theLastPresamplingMomenta,GeV) >> theLastRandomNumbers
>> theLastBornXComb >> theLastPartons >> theDoCompensate;
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<ShowerApproximationGenerator,StepHandler>
describeHerwigShowerApproximationGenerator("Herwig::ShowerApproximationGenerator", "Herwig.so");
void ShowerApproximationGenerator::Init() {
static ClassDocumentation<ShowerApproximationGenerator> documentation
("ShowerApproximationGenerator generates emissions according to a "
"shower approximation entering a NLO matching.");
static Reference<ShowerApproximationGenerator,ShowerApproximation> interfaceShowerApproximation
("ShowerApproximation",
"Set the shower approximation to sample.",
&ShowerApproximationGenerator::theShowerApproximation, false, false, true, false, false);
interfaceShowerApproximation.rank(-1);
static Reference<ShowerApproximationGenerator,MatchboxPhasespace> interfacePhasespace
("Phasespace",
"The phase space generator to use.",
&ShowerApproximationGenerator::thePhasespace, false, false, true, false, false);
interfacePhasespace.rank(-1);
static Parameter<ShowerApproximationGenerator,unsigned long> interfacePresamplingPoints
("PresamplingPoints",
"Set the number of presampling points.",
&ShowerApproximationGenerator::thePresamplingPoints, 2000, 1, 0,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximationGenerator,unsigned long> interfaceMaxTry
("MaxTry",
"Set the number of maximum attempts.",
&ShowerApproximationGenerator::theMaxTry, 100000, 1, 0,
false, false, Interface::lowerlim);
static Parameter<ShowerApproximationGenerator,unsigned long> interfaceFreezeGrid
("FreezeGrid",
"",
&ShowerApproximationGenerator::theFreezeGrid, 500000, 1, 0,
false, false, Interface::lowerlim);
static Switch<ShowerApproximationGenerator,bool> interfaceDoCompensate
("DoCompensate",
"",
&ShowerApproximationGenerator::theDoCompensate, false, false, false);
static SwitchOption interfaceDoCompensateYes
(interfaceDoCompensate,
"Yes",
"",
true);
static SwitchOption interfaceDoCompensateNo
(interfaceDoCompensate,
"No",
"",
false);
}
diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.h b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.h
--- a/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.h
+++ b/MatrixElement/Matchbox/Matching/ShowerApproximationGenerator.h
@@ -1,251 +1,243 @@
// -*- C++ -*-
//
// ShowerApproximationGenerator.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_ShowerApproximationGenerator_H
#define Herwig_ShowerApproximationGenerator_H
//
// This is the declaration of the ShowerApproximationGenerator class.
//
#include "ThePEG/Handlers/StepHandler.h"
#include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief ShowerApproximationGenerator generates emissions according to a
* shower approximation entering a NLO matching.
*
*/
class ShowerApproximationGenerator: public StepHandler {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
ShowerApproximationGenerator();
- /**
- * The destructor.
- */
- virtual ~ShowerApproximationGenerator();
- //@}
-
public:
/** @name Virtual functions required by the StepHandler class. */
//@{
/**
* The main function called by the EventHandler class to
* perform a step. Given the current state of an Event, this function
* performs the event generation step and includes the result in a new
* Step object int the Event record.
* @param eh the EventHandler in charge of the Event generation.
* @param tagged if not empty these are the only particles which should
* be considered by the StepHandler.
* @param hint a Hint object with possible information from previously
* performed steps.
* @throws Veto if the StepHandler requires the current step to be discarded.
* @throws Stop if the generation of the current Event should be stopped
* after this call.
* @throws Exception if something goes wrong.
*/
virtual void handle(EventHandler & eh, const tPVector & tagged,
const Hint & hint);
//@}
public:
/**
* Fill information on the Born process
*/
bool prepare(bool didproject);
/**
* Generate a Born phase space point while kernels are being
* presampled
*/
bool generate(const vector<double>&);
/**
* Restore information on the Born process
*/
void restore();
protected:
/**
* Generate a momentum fraction for the given parton species
*/
double generateFraction(tcPDPtr, double, double) const;
/**
* Invert the momentum fraction for the given parton species
*/
double invertFraction(tcPDPtr, double, double) const;
/**
* Return the pt cut to be applied for final-final dipoles.
*/
Energy ffPtCut() const { return theShowerApproximation->ffPtCut(); }
/**
* Return the pt cut to be applied for final-initial dipoles.
*/
Energy fiPtCut() const { return theShowerApproximation->fiPtCut(); }
/**
* Return the pt cut to be applied for initial-initial dipoles.
*/
Energy iiPtCut() const { return theShowerApproximation->iiPtCut(); }
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 shower approximation to consider
*/
Ptr<ShowerApproximation>::ptr theShowerApproximation;
/**
* The (invertible) phase space generator to use
*/
Ptr<MatchboxPhasespace>::ptr thePhasespace;
/**
* Map hard processes to the respective kernels.
*/
map<cPDVector,set<Ptr<ShowerApproximationKernel>::ptr> > theKernelMap;
/**
* The number of points to presample this splitting generator.
*/
unsigned long thePresamplingPoints;
/**
* The maximum number of trials to generate a splitting.
*/
unsigned long theMaxTry;
/**
* Return the number of accepted points after which the grid should
* be frozen
*/
unsigned long theFreezeGrid;
/**
* The last external Born XComb dealt with
*/
tStdXCombPtr lastIncomingXComb;
// the next three are filled from the incoming xcomb in the prepare method
/**
* The last internal Born matrix element dealt with
*/
Ptr<MatchboxMEBase>::ptr theLastBornME;
/**
* The last Born phase space point
*/
vector<Lorentz5Momentum> theLastMomenta;
/**
* The last Born phase space point used while presampling
*/
vector<Lorentz5Momentum> theLastPresamplingMomenta;
/**
* The random numbers which have produced the last Born phase space
* point.
*/
vector<double> theLastRandomNumbers;
/**
* The last internal Born XComb dealt with
*/
tStdXCombPtr theLastBornXComb;
/**
* The last internal incoming partons dealt with
*/
PPair theLastPartons;
/**
* True, if sampler should apply compensation
*/
bool theDoCompensate;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
ShowerApproximationGenerator & operator=(const ShowerApproximationGenerator &) = delete;
};
}
#endif /* Herwig_ShowerApproximationGenerator_H */
diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.cc b/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.cc
--- a/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.cc
+++ b/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.cc
@@ -1,210 +1,208 @@
// -*- C++ -*-
//
// ShowerApproximationKernel.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 ShowerApproximationKernel class.
//
#include <config.h>
#include "ShowerApproximationKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ShowerApproximationGenerator.h"
using namespace Herwig;
ShowerApproximationKernel::ShowerApproximationKernel()
: thePresampling(false), thePresamplingPoints(10000),
theMaxTry(100000), theFreezeGrid(500000),
sampler(0), theDoCompensate(false) {}
-ShowerApproximationKernel::~ShowerApproximationKernel() {}
-
IBPtr ShowerApproximationKernel::clone() const {
return new_ptr(*this);
}
IBPtr ShowerApproximationKernel::fullclone() const {
return new_ptr(*this);
}
void ShowerApproximationKernel::showerApproximationGenerator(Ptr<ShowerApproximationGenerator>::tptr gen) {
theShowerApproximationGenerator = gen;
}
Ptr<ShowerApproximationGenerator>::tptr ShowerApproximationKernel::showerApproximationGenerator() const {
return theShowerApproximationGenerator;
}
const vector<bool>& ShowerApproximationKernel::sampleFlags() {
if ( !theFlags.empty() )
return theFlags;
theFlags.resize(nDim(),false);
for ( int k = nDimBorn();
k < nDimBorn() + dipole()->nDimRadiation(); ++k )
theFlags[k] = true;
return theFlags;
}
const pair<vector<double>,vector<double> >& ShowerApproximationKernel::support() {
if ( !theSupport.first.empty() )
return theSupport;
vector<double> l(nDim(),0.0);
vector<double> u(nDim(),1.0);
theSupport.first = l;
theSupport.second = u;
return theSupport;
}
const vector<double>& ShowerApproximationKernel::parameterPoint() {
theLastParameterPoint.resize(nDim());
copy(bornCXComb()->lastRandomNumbers().begin(),
bornCXComb()->lastRandomNumbers().end(),
theLastParameterPoint.begin());
theLastParameterPoint[evolutionVariable()] = 1.;
return theLastParameterPoint;
}
void ShowerApproximationKernel::startPresampling() {
thePresampling = true;
}
void ShowerApproximationKernel::stopPresampling() {
showerApproximationGenerator()->restore();
thePresampling = false;
}
double ShowerApproximationKernel::evaluate(const vector<double>& r) {
if ( presampling() ) {
theLastBornPoint.resize(nDimBorn());
copy(r.begin(),r.begin()+nDimBorn(),theLastBornPoint.begin());
if ( !showerApproximationGenerator()->generate(theLastBornPoint) )
return 0.;
}
assert(dipole()->splitting());
realXComb()->clean();
dipole()->setXComb(realXComb());
for ( vector<StdXCombPtr>::const_iterator t = tildeXCombs().begin();
t != tildeXCombs().end(); ++t ) {
(**t).clean();
(**t).matrixElement()->setXComb(*t);
}
if ( !dipole()->generateKinematics(&r[nDimBorn()]) )
return 0.;
double jac =
showerApproximation()->showerInvertedTildeKinematics() ?
showerApproximation()->showerInvertedTildeKinematics()->jacobian() :
dipole()->invertedTildeKinematics()->jacobian();
showerApproximation()->setBornXComb(bornXComb());
showerApproximation()->setRealXComb(realXComb());
showerApproximation()->setTildeXCombs(tildeXCombs());
showerApproximation()->setDipole(dipole());
showerApproximation()->checkCutoff();
showerApproximation()->getShowerVariables();
if ( !dipole()->isInShowerPhasespace() )
return 0.;
return showerApproximation()->me2() * jac;
}
double ShowerApproximationKernel::generate() {
if ( !sampler ) {
sampler = new ExponentialGenerator();
sampler->sampling_parameters().maxtry = maxtry();
sampler->sampling_parameters().presampling_points = presamplingPoints();
sampler->sampling_parameters().freeze_grid = freezeGrid();
sampler->docompensate(theDoCompensate);
sampler->function(this);
sampler->initialize();
}
double res = 0.;
while (true) {
try {
res = sampler->generate();
} catch (exsample::exponential_regenerate&) {
continue;
} catch (exsample::hit_and_miss_maxtry&) {
throw MaxTryException();
} catch (exsample::selection_maxtry&) {
throw MaxTryException();
}
break;
}
return res;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void ShowerApproximationKernel::persistentOutput(PersistentOStream & os) const {
os << theDipole << theShowerApproximation << theBornXComb
<< theRealXComb << theTildeXCombs << thePresampling
<< thePresamplingPoints << theMaxTry << theFreezeGrid << theFlags
<< theSupport << theShowerApproximationGenerator
<< theLastParameterPoint << theLastBornPoint
<< (sampler ? true : false) << theDoCompensate;
if ( sampler )
sampler->put(os);
}
void ShowerApproximationKernel::persistentInput(PersistentIStream & is, int) {
bool haveSampler;
is >> theDipole >> theShowerApproximation >> theBornXComb
>> theRealXComb >> theTildeXCombs >> thePresampling
>> thePresamplingPoints >> theMaxTry >> theFreezeGrid >> theFlags
>> theSupport >> theShowerApproximationGenerator
>> theLastParameterPoint >> theLastBornPoint
>> haveSampler >> theDoCompensate;
if ( haveSampler ) {
sampler = new ExponentialGenerator();
sampler->get(is);
sampler->function(this);
sampler->initialize();
}
}
// *** 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<ShowerApproximationKernel,HandlerBase>
describeHerwigShowerApproximationKernel("Herwig::ShowerApproximationKernel", "Herwig.so");
void ShowerApproximationKernel::Init() {
static ClassDocumentation<ShowerApproximationKernel> documentation
("ShowerApproximationKernel generates emissions according to a "
"shower approximation entering a NLO matching.");
}
diff --git a/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.h b/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.h
--- a/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.h
+++ b/MatrixElement/Matchbox/Matching/ShowerApproximationKernel.h
@@ -1,478 +1,470 @@
// -*- C++ -*-
//
// ShowerApproximationKernel.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_ShowerApproximationKernel_H
#define Herwig_ShowerApproximationKernel_H
//
// This is the declaration of the ShowerApproximationKernel class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
#include "Herwig/Sampling/exsample/exponential_generator.h"
namespace Herwig {
using namespace ThePEG;
class ShowerApproximationGenerator;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief ShowerApproximationKernel generates emissions according to a
* shower approximation entering a NLO matching.
*
*/
class ShowerApproximationKernel: public HandlerBase {
public:
/**
* Exception to communicate sampler maxtry events.
*/
struct MaxTryException {};
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
ShowerApproximationKernel();
- /**
- * The destructor.
- */
- virtual ~ShowerApproximationKernel();
- //@}
-
public:
/**
* Set the XComb object describing the Born process
*/
void setBornXComb(tStdXCombPtr xc) { theBornXComb = xc; }
/**
* Return the XComb object describing the Born process
*/
tcStdXCombPtr bornCXComb() const { return theBornXComb; }
/**
* Return the XComb object describing the Born process
*/
tStdXCombPtr bornXComb() const { return theBornXComb; }
/**
* Set the XComb object describing the real emission process
*/
void setRealXComb(tStdXCombPtr xc) { theRealXComb = xc; }
/**
* Return the XComb object describing the real emission process
*/
tcStdXCombPtr realCXComb() const { return theRealXComb; }
/**
* Return the XComb object describing the real emission process
*/
tStdXCombPtr realXComb() const { return theRealXComb; }
/**
* Set the tilde xcomb objects associated to the real xcomb
*/
void setTildeXCombs(const vector<StdXCombPtr>& xc) { theTildeXCombs = xc; }
/**
* Return the tilde xcomb objects associated to the real xcomb
*/
const vector<StdXCombPtr>& tildeXCombs() const { return theTildeXCombs; }
/**
* Set the dipole in charge for the emission
*/
void setDipole(Ptr<SubtractionDipole>::tptr dip) { theDipole = dip; }
/**
* Return the dipole in charge for the emission
*/
Ptr<SubtractionDipole>::tptr dipole() const { return theDipole; }
/**
* Set the shower approximation.
*/
void showerApproximation(Ptr<ShowerApproximation>::tptr app) { theShowerApproximation = app; }
/**
* Return the shower approximation.
*/
Ptr<ShowerApproximation>::tptr showerApproximation() const { return theShowerApproximation; }
/**
* Set the shower approximation generator.
*/
void showerApproximationGenerator(Ptr<ShowerApproximationGenerator>::tptr);
/**
* Return the shower approximation generator.
*/
Ptr<ShowerApproximationGenerator>::tptr showerApproximationGenerator() const;
/**
* Generate the next emission
*/
double generate();
public:
/**
* Set a pt cut on the dipole to generate the radiation
*/
void ptCut(Energy pt) { dipole()->ptCut(pt); }
/**
* Return the number of random numbers
* needed to sample this kernel.
*/
int nDim() const {
return
nDimBorn() +
dipole()->nDimRadiation();
}
/**
* Return the number of random numbers
* needed to sample the Born process.
*/
int nDimBorn() const {
return bornCXComb()->lastRandomNumbers().size();
}
/**
* Flag, which variables are free variables.
*/
const vector<bool>& sampleFlags();
/**
* Return the support of the splitting kernel.
* The lower bound on the first variable is
* assumed to correspond to the cutoff on the
* evolution variable.
*/
const pair<vector<double>,vector<double> >& support();
/**
* Return the parameter point associated to the splitting
* previously supplied through fixParameters.
*/
const vector<double>& parameterPoint();
/**
* Indicate that presampling of this kernel
* will be performed in the next calls to
* evaluate until stopPresampling() is called.
*/
void startPresampling();
/**
* Indicate that presampling of this kernel
* is done until startPresampling() is called.
*/
void stopPresampling();
/**
* Indicate that a veto with the given kernel value and overestimate has occured.
*/
void veto(const vector<double>&, double, double) {
/** use born and real xcombs in here to figure out what we need to reweight;
it should have its kinematic variables completed at this step */
}
/**
* Indicate that an accept with the given kernel value and overestimate has occured.
*/
void accept(const vector<double>&, double, double) {
/** use born and real xcombs in here to figure out what we need to reweight;
it should have its kinematic variables completed at this step */
}
/**
* Return true, if currently being presampled
*/
bool presampling() const { return thePresampling; }
/**
* Return the number of points to presample this
* splitting generator.
*/
unsigned long presamplingPoints() const { return thePresamplingPoints; }
/**
* Return the maximum number of trials
* to generate a splitting.
*/
unsigned long maxtry() const { return theMaxTry; }
/**
* Return the number of accepted points after which the grid should
* be frozen
*/
unsigned long freezeGrid() const { return theFreezeGrid; }
/**
* Set the number of points to presample this
* splitting generator.
*/
void presamplingPoints(unsigned long p) { thePresamplingPoints = p; }
/**
* Set the maximum number of trials
* to generate a splitting.
*/
void maxtry(unsigned long p) { theMaxTry = p; }
/**
* Set the number of accepted points after which the grid should
* be frozen
*/
void freezeGrid(unsigned long n) { theFreezeGrid = n; }
/**
* Evalute the splitting kernel.
*/
double evaluate(const vector<double>&);
/**
* Return the index of the random number corresponding
* to the evolution variable.
*/
int evolutionVariable() const {
return
nDimBorn() +
(showerApproximation()->showerInvertedTildeKinematics() ?
showerApproximation()->showerInvertedTildeKinematics()->evolutionVariable() :
dipole()->invertedTildeKinematics()->evolutionVariable());
}
/**
* Return the cutoff on the evolution
* random number corresponding to the pt cut.
*/
double evolutionCutoff() const {
return
showerApproximation()->showerInvertedTildeKinematics() ?
showerApproximation()->showerInvertedTildeKinematics()->evolutionCutoff() :
dipole()->invertedTildeKinematics()->evolutionCutoff();
}
/**
* True, if sampler should apply compensation
*/
void doCompensate(bool yes = true) { theDoCompensate = yes; }
public:
/**@name Wrap to the exsample2 interface until this is finally cleaned up. */
//@{
inline const vector<bool>& variable_flags () {
return sampleFlags();
}
inline size_t evolution_variable () const { return evolutionVariable(); }
inline double evolution_cutoff () const {
return evolutionCutoff();
}
inline const vector<double>& parameter_point () {
return parameterPoint();
}
inline void start_presampling () {
startPresampling();
}
inline void stop_presampling () {
stopPresampling();
}
inline size_t dimension () const {
return nDim();
}
inline unsigned long presampling_points () const {
return presamplingPoints();
}
//@}
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 dipole in charge of the emission
*/
Ptr<SubtractionDipole>::ptr theDipole;
/**
* The shower approximation to consider
*/
Ptr<ShowerApproximation>::ptr theShowerApproximation;
/**
* The XComb off which radiation will be generated
*/
StdXCombPtr theBornXComb;
/**
* The XComb describing the process after radiation
*/
StdXCombPtr theRealXComb;
/**
* The tilde xcomb objects associated to the real xcomb
*/
vector<StdXCombPtr> theTildeXCombs;
/**
* True, if currently being presampled
*/
bool thePresampling;
/**
* The number of points to presample this
* splitting generator.
*/
unsigned long thePresamplingPoints;
/**
* The maximum number of trials
* to generate a splitting.
*/
unsigned long theMaxTry;
/**
* Return the number of accepted points after which the grid should
* be frozen
*/
unsigned long theFreezeGrid;
/**
* The sampling flags
*/
vector<bool> theFlags;
/**
* The support.
*/
pair<vector<double>,vector<double> > theSupport;
/**
* The shower approximation generator.
*/
Ptr<ShowerApproximationGenerator>::tptr theShowerApproximationGenerator;
/**
* The last parameter point
*/
vector<double> theLastParameterPoint;
/**
* The last random numbers used for Born sampling
*/
vector<double> theLastBornPoint;
/**
* Define the Sudakov sampler
*/
typedef
exsample::exponential_generator<ShowerApproximationKernel,UseRandom>
ExponentialGenerator;
/**
* Define a pointer to the Sudakov sampler
*/
typedef
exsample::exponential_generator<ShowerApproximationKernel,UseRandom>*
ExponentialGeneratorPtr;
/**
* The Sudakov sampler
*/
ExponentialGeneratorPtr sampler;
/**
* True, if sampler should apply compensation
*/
bool theDoCompensate;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
ShowerApproximationKernel & operator=(const ShowerApproximationKernel &) = delete;
};
}
#endif /* Herwig_ShowerApproximationKernel_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.cc
@@ -1,137 +1,133 @@
// -*- C++ -*-
//
// FFLightInvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FFLightInvertedTildeKinematics class.
//
#include "FFLightInvertedTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-FFLightInvertedTildeKinematics::FFLightInvertedTildeKinematics() {}
-
-FFLightInvertedTildeKinematics::~FFLightInvertedTildeKinematics() {}
-
IBPtr FFLightInvertedTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FFLightInvertedTildeKinematics::fullclone() const {
return new_ptr(*this);
}
bool FFLightInvertedTildeKinematics::doMap(const double * r) {
if ( ptMax() < ptCut() ) {
jacobian(0.0);
return false;
}
Lorentz5Momentum emitter = bornEmitterMomentum();
Lorentz5Momentum spectator = bornSpectatorMomentum();
double mapping = 1.0;
pair<Energy,double> ptz = generatePtZ(mapping,r);
if ( mapping == 0.0 ) {
jacobian(0.0);
return false;
}
Energy pt = ptz.first;
double z = ptz.second;
double y = sqr(pt/lastScale())/(z*(1.-z));
if ( y < 0. || y > 1. ||
z < 0. || z > 1. ) {
jacobian(0.0);
return false;
}
mapping *= (1.-y)/(z*(1.-z));
jacobian(mapping*(sqr(lastScale())/sHat())/(16.*sqr(Constants::pi)));
double phi = 2.*Constants::pi*r[2];
Lorentz5Momentum kt
= getKt(emitter,spectator,pt,phi);
subtractionParameters().resize(2);
subtractionParameters()[0] = y;
subtractionParameters()[1] = z;
realEmitterMomentum() = z*emitter + y*(1.-z)*spectator + kt;
realEmissionMomentum() = (1.-z)*emitter + y*z*spectator - kt;
realSpectatorMomentum() = (1.-y)*spectator;
realEmitterMomentum().setMass(ZERO);
realEmitterMomentum().rescaleEnergy();
realEmissionMomentum().setMass(ZERO);
realEmissionMomentum().rescaleEnergy();
realSpectatorMomentum().setMass(ZERO);
realSpectatorMomentum().rescaleEnergy();
return true;
}
Energy FFLightInvertedTildeKinematics::lastPt() const {
Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum()));
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
return scale * sqrt(y*z*(1.-z));
}
double FFLightInvertedTildeKinematics::lastZ() const {
return subtractionParameters()[1];
}
Energy FFLightInvertedTildeKinematics::ptMax() const {
return lastScale()/2.;
}
pair<double,double> FFLightInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax());
if(pt>hardPt) return make_pair(0.5,0.5);
double s = sqrt(1.-sqr(pt/hardPt));
return make_pair(0.5*(1.-s),0.5*(1.+s));
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFLightInvertedTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void FFLightInvertedTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void FFLightInvertedTildeKinematics::Init() {
static ClassDocumentation<FFLightInvertedTildeKinematics> documentation
("FFLightInvertedTildeKinematics inverts the final-final tilde "
"kinematics.");
}
// *** 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<FFLightInvertedTildeKinematics,InvertedTildeKinematics>
describeHerwigFFLightInvertedTildeKinematics("Herwig::FFLightInvertedTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/FFLightInvertedTildeKinematics.h
@@ -1,138 +1,123 @@
// -*- C++ -*-
//
// FFLightInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFLightInvertedTildeKinematics_H
#define HERWIG_FFLightInvertedTildeKinematics_H
//
// This is the declaration of the FFLightInvertedTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FFLightInvertedTildeKinematics inverts the final-final tilde
* kinematics.
*
*/
class FFLightInvertedTildeKinematics: public Herwig::InvertedTildeKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- FFLightInvertedTildeKinematics();
-
- /**
- * The destructor.
- */
- virtual ~FFLightInvertedTildeKinematics();
- //@}
-
-public:
-
/**
* Perform the mapping of the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the real
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap(const double *);
/**
* Return the pt associated to the last generated splitting.
*/
virtual Energy lastPt() const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
/**
* Return the upper bound on pt
*/
virtual Energy ptMax() const;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt = ZERO) 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.
*/
FFLightInvertedTildeKinematics & operator=(const FFLightInvertedTildeKinematics &) = delete;
};
}
#endif /* HERWIG_FFLightInvertedTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/FFLightTildeKinematics.cc
@@ -1,114 +1,109 @@
// -*- C++ -*-
//
// FFLightTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FFLightTildeKinematics class.
//
#include "FFLightTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-FFLightTildeKinematics::FFLightTildeKinematics() {}
-
-FFLightTildeKinematics::~FFLightTildeKinematics() {}
-
IBPtr FFLightTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FFLightTildeKinematics::fullclone() const {
return new_ptr(*this);
}
bool FFLightTildeKinematics::doMap() {
Lorentz5Momentum emitter = realEmitterMomentum();
Lorentz5Momentum emission = realEmissionMomentum();
Lorentz5Momentum spectator = realSpectatorMomentum();
double y = emission*emitter / (emission*emitter + emission*spectator + emitter*spectator);
double z = emitter*spectator / (emitter*spectator + emission*spectator);
subtractionParameters().resize(2);
subtractionParameters()[0] = y;
subtractionParameters()[1] = z;
bornEmitterMomentum() = emitter+emission-(y/(1.-y))*spectator;
bornSpectatorMomentum() = spectator/(1.-y);
bornEmitterMomentum().setMass(ZERO);
bornEmitterMomentum().rescaleEnergy();
bornSpectatorMomentum().setMass(ZERO);
bornSpectatorMomentum().rescaleEnergy();
return true;
}
Energy FFLightTildeKinematics::lastPt() const {
Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum()));
double y = subtractionParameters()[0];
double z = subtractionParameters()[1];
return scale * sqrt(y*z*(1.-z));
}
Energy FFLightTildeKinematics::lastPt(Lorentz5Momentum emitter,Lorentz5Momentum emission,Lorentz5Momentum spectator)const {
Energy scale = (emitter+emission+spectator).m();
double y = emission*emitter/(emission*emitter + emission*spectator + emitter*spectator);
double z = emitter*spectator / (emitter*spectator + emission*spectator);
Energy ret = scale * sqrt( y * z*(1.-z) );
return ret;
}
pair<double,double> FFLightTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
if(pt>hardPt) return make_pair(0.5,0.5);
double s = sqrt(1.-sqr(pt/hardPt));
return make_pair(0.5*(1.-s),0.5*(1.+s));
}
double FFLightTildeKinematics::lastZ() const {
return subtractionParameters()[1];
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFLightTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void FFLightTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void FFLightTildeKinematics::Init() {
static ClassDocumentation<FFLightTildeKinematics> documentation
("FFLightTildeKinematics implements the 'tilde' kinematics for "
"a final-final subtraction dipole.");
}
// *** 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<FFLightTildeKinematics,TildeKinematics>
describeHerwigFFLightTildeKinematics("Herwig::FFLightTildeKinematics", "Herwig.so");
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,144 +1,129 @@
// -*- C++ -*-
//
// FFLightTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 pt associated to emitter emission and sppectator momentum.
*/
virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt ) 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 &) = delete;
};
}
#endif /* HERWIG_FFLightTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.cc
@@ -1,325 +1,319 @@
// -*- C++ -*-
//
// FFMassiveInvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FFMassiveInvertedTildeKinematics class.
//
#include "FFMassiveInvertedTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/EventGenerator.h"
-
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
-
#include "Herwig/MatrixElement/Matchbox/Phasespace/RandomHelpers.h"
using namespace Herwig;
-FFMassiveInvertedTildeKinematics::FFMassiveInvertedTildeKinematics() {}
-
-FFMassiveInvertedTildeKinematics::~FFMassiveInvertedTildeKinematics() {}
-
IBPtr FFMassiveInvertedTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FFMassiveInvertedTildeKinematics::fullclone() const {
return new_ptr(*this);
}
// Matches Stephen Webster's thesis
bool FFMassiveInvertedTildeKinematics::doMap(const double * r) {
if ( ptMax() < ptCut() ) {
jacobian(0.0);
return false;
}
Lorentz5Momentum emitter = bornEmitterMomentum();
Lorentz5Momentum spectator = bornSpectatorMomentum();
double mapping = 1.0;
vector<double> values(6);
pair<Energy,double> ptz = generatePtZ(mapping, r, &values);
if ( mapping == 0.0 ) {
jacobian(0.0);
return false;
}
Energy pt = ptz.first;
Energy2 pt2 = sqr(pt);
double z = ptz.second;
// masses
double mui2 = sqr( realEmitterData()->hardProcessMass() / lastScale() );
double muj2 = sqr( realEmissionData()->hardProcessMass() / lastScale() );
double muk2 = sqr( realSpectatorData()->hardProcessMass() / lastScale() );
double Muij2 = sqr( bornEmitterData()->hardProcessMass() / lastScale() );
double Muk2 = sqr( bornSpectatorData()->hardProcessMass() / lastScale() );
// Define the scale
Energy2 Qijk = sqr(lastScale());
// Most of the required values have been calculated in ptzAllowed
double y = values[0];
double zi = values[1];
double xk = values[2];
double xij = values[3];
double QijN2 = values[4];
double sijkN = values[5];
double sijkN2 = sqr(sijkN);
// Construct reference momenta nk, nij
Lorentz5Momentum nij = ( sijkN2 / (sijkN2-Muij2*Muk2) )
* (emitter - (Muij2/sijkN)*spectator);
Lorentz5Momentum nk = ( sijkN2 / (sijkN2-Muij2*Muk2) )
* (spectator - (Muk2/sijkN)*emitter);
// Construct qt
double phi = 2.*Constants::pi*r[2];
Lorentz5Momentum qt = getKt(emitter,spectator,pt,phi);
// Construct qij, qk, qi and qj
Lorentz5Momentum qij = xij*nij + (Muij2/(xij*sijkN))*nk;
Lorentz5Momentum spe = xk*nk + (Muk2/(xk*sijkN))*nij;
Lorentz5Momentum em = z*qij
+ ((pt2/Qijk + mui2 - z*z*Muij2)/(xij*sijkN*z))*nk + qt;
Lorentz5Momentum emm = (1.-z)*qij
+ ((pt2/Qijk + muj2 - sqr(1.-z)*Muij2)/(xij*sijkN*(1.-z)))*nk - qt;
em.setMass(realEmitterData()->hardProcessMass());
em.rescaleEnergy();
emm.setMass(realEmissionData()->hardProcessMass());
emm.rescaleEnergy();
spe.setMass(realSpectatorData()->hardProcessMass());
spe.rescaleEnergy();
// book
realEmitterMomentum() = em;
realEmissionMomentum() = emm;
realSpectatorMomentum() = spe;
// Calculate the jacobian
double bar = 1.-mui2-muj2-muk2;
// mapFactor defined as dy dz = mapFactor * dpt2/sqr(lastScale()) dz
double mapFactor = 0.0;
mapFactor = y*(sqr(lastScale()) / (pt2 + sqr(1.-z)*mui2*Qijk + sqr(z)*muj2*Qijk))
* abs(1. - 2.*Muk2*QijN2 / (bar*(1.-y)*xij*xk*sijkN));
// Mapping includes only the variable changes/jacobians
mapping *= mapFactor;
jacobian( (Qijk*sqr(bar)/rootOfKallen(1.,Muij2,Muk2)) * mapping
* (1.-y)/(16.*sqr(Constants::pi)) / sHat() );
// Store the parameters
subtractionParameters().resize(3);
subtractionParameters()[0] = y;
subtractionParameters()[1] = zi;
subtractionParameters()[2] = z;
return true;
}
Energy FFMassiveInvertedTildeKinematics::lastPt() const {
Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m();
// masses
double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
double muj2 = sqr( realEmissionData()->hardProcessMass() / scale );
double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
double y = subtractionParameters()[0];
double z = subtractionParameters()[2];
Energy ret = scale * sqrt( y * (1.-mui2-muj2-muk2) * z*(1.-z) - sqr(1.-z)*mui2 - sqr(z)*muj2 );
return ret;
}
double FFMassiveInvertedTildeKinematics::lastZ() const {
return subtractionParameters()[2];
}
Energy FFMassiveInvertedTildeKinematics::ptMax() const {
Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m();
// masses
double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
double muj2 = sqr( realEmissionData()->hardProcessMass() / scale );
double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
Energy ptmax = rootOfKallen( mui2, muj2, sqr(1.-sqrt(muk2)) ) /
( 2.-2.*sqrt(muk2) ) * scale;
return ptmax > 0.*GeV ? ptmax : 0.*GeV;
}
// NOTE: bounds calculated at this step may be too loose
pair<double,double> FFMassiveInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax());
if(pt>hardPt) return make_pair(0.5,0.5);
Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m();
// masses
double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
double muj2 = sqr( realEmissionData()->hardProcessMass() / scale );
double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
double zp = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) +
rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) *
sqrt( 1.-sqr(pt/hardPt) ) ) /
( 2.*sqr(1.-sqrt(muk2)) );
double zm = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) -
rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) *
sqrt( 1.-sqr(pt/hardPt) ) ) /
( 2.*sqr(1.-sqrt(muk2)) );
return make_pair(zm,zp);
}
// Matches Stephen Webster's thesis
bool FFMassiveInvertedTildeKinematics::ptzAllowed(pair<Energy,double> ptz, vector<double>* values) const {
Energy pt = ptz.first;
Energy2 pt2 = sqr(pt);
double z = ptz.second;
// masses
double mui2 = sqr( realEmitterData()->hardProcessMass() / lastScale() );
double muj2 = sqr( realEmissionData()->hardProcessMass() / lastScale() );
double muk2 = sqr( realSpectatorData()->hardProcessMass() / lastScale() );
double Muij2 = sqr( bornEmitterData()->hardProcessMass() / lastScale() );
double Muk2 = sqr( bornSpectatorData()->hardProcessMass() / lastScale() );
// Calculate the scales that we need
Energy2 Qijk = sqr(lastScale());
double QijN2 = (pt2/Qijk + (1.-z)*mui2 + z*muj2) / z / (1.-z);
double sijkN = 0.5*( 1. - Muij2 - Muk2 + sqrt( sqr(1.-Muij2-Muk2) - 4.*Muij2*Muk2 ) );
double bar = 1.-mui2-muj2-muk2;
double y = ( pt2/Qijk + sqr(1.-z)*mui2 + z*z*muj2 ) /
(z*(1.-z)*bar);
// Calculate the scaling factors, xk and xij
double lambdaK = 1. + (Muk2/sijkN);
double lambdaIJ = 1. + (Muij2/sijkN);
double fac1 = lambdaIJ*lambdaK + (muk2 - QijN2)/sijkN;
double xk =
( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*muk2/sijkN ) )
/ 2. / lambdaK ;
double xij = 1. - muk2*(1.-xk) / xk / sijkN;
// Calculate zi
double zi =
( z*xij*xk*sijkN + muk2*(pt2/Qijk + mui2) / (z*xij*xk*sijkN) )
/ (1.-y) / bar;
// Limits on zi
double facA = (2.*mui2+bar*y)/2./(mui2 + muj2 + bar*y);
double facB =
sqrt( (sqr(2.*muk2 + bar*(1.-y)) - 4.*muk2) *
(sqr(bar)*sqr(y) - 4.*mui2*muj2))
/ bar / (1.-y) / (bar*y + 2.*mui2);
double zim = facA * (1. - facB);
double zip = facA * (1. + facB);
// check (y,z) phase space boundary
double ym = 2.*sqrt(mui2)*sqrt(muj2)/bar;
double yp = 1. - 2.*sqrt(muk2)*(1.-sqrt(muk2))/bar;
if ( y<ym || y>yp || zi<zim || zi>zip ) return false;
assert( (*values).size() == 6);
(*values)[0] = y;
(*values)[1] = zi;
(*values)[2] = xk;
(*values)[3] = xij;
(*values)[4] = QijN2;
(*values)[5] = sijkN;
return true;
}
// This is used to generate pt and z
pair<Energy,double> FFMassiveInvertedTildeKinematics::generatePtZ(double& jac, const double * r, vector<double> * values) const {
double kappaMin =
ptCut() != ZERO ?
sqr(ptCut()/ptMax()) :
sqr(0.1*GeV/GeV);
double kappa;
using namespace RandomHelpers;
if ( ptCut() > ZERO ) {
pair<double,double> kw =
generate(inverse(0.,kappaMin,1.),r[0]);
kappa = kw.first;
jac *= kw.second;
} else {
pair<double,double> kw =
generate((piecewise(),
flat(1e-4,kappaMin),
match(inverse(0.,kappaMin,1.))),r[0]);
kappa = kw.first;
jac *= kw.second;
}
Energy pt = sqrt(kappa)*ptMax();
pair<double,double> zLims = zBounds(pt);
pair<double,double> zw =
generate(inverse(0.,zLims.first,zLims.second)+
inverse(1.,zLims.first,zLims.second),r[1]);
double z = zw.first;
jac *= zw.second;
jac *= sqr(ptMax()/lastScale());
if( !ptzAllowed(make_pair(pt,z), values )) jac = 0.;
return make_pair(pt,z);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFMassiveInvertedTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void FFMassiveInvertedTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void FFMassiveInvertedTildeKinematics::Init() {
static ClassDocumentation<FFMassiveInvertedTildeKinematics> documentation
("FFMassiveInvertedTildeKinematics inverts the final-final tilde "
"kinematics involving a massive particle.");
}
// *** 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<FFMassiveInvertedTildeKinematics,InvertedTildeKinematics>
describeHerwigFFMassiveInvertedTildeKinematics("Herwig::FFMassiveInvertedTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/FFMassiveInvertedTildeKinematics.h
@@ -1,179 +1,164 @@
// -*- C++ -*-
//
// FFMassiveInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFMassiveInvertedTildeKinematics_H
#define HERWIG_FFMassiveInvertedTildeKinematics_H
//
// This is the declaration of the FFMassiveInvertedTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Stephen Webster
*
* \brief FFMassiveInvertedTildeKinematics inverts the final-final tilde
* kinematics.
*
*/
class FFMassiveInvertedTildeKinematics: public Herwig::InvertedTildeKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- FFMassiveInvertedTildeKinematics();
-
- /**
- * The destructor.
- */
- virtual ~FFMassiveInvertedTildeKinematics();
- //@}
-
-public:
-
/**
* Perform the mapping of the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the real
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap(const double *);
/**
* Return the pt associated to the last generated splitting.
*/
virtual Energy lastPt() const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
/**
* Return the upper bound on pt
*/
virtual Energy ptMax() const;
/**
* Given a pt, return the boundaries on z
* Note that allowing parton masses these bounds may be too loose
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt = ZERO) const;
/**
* For generated pt and z, check if this point is
* kinematically allowed
*/
/*virtual*/ bool ptzAllowed(pair<Energy,double> ptz, vector<double>* values ) const;
/**
* Generate pt and z
*/
virtual pair<Energy,double> generatePtZ(double& jac, const double * r, vector<double>* values) const;
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline T rootOfKallen (T a, T b, T c) const {
return sqrt( a*a + b*b + c*c - 2.*( a*b+a*c+b*c ) ); }
// TODO: remove in both
/**
* stolen from FFMassiveKinematics.h
* Perform a rotation on both momenta such that the first one will
* point along the (positive) z axis. Rotate back to the original
* reference frame by applying rotateUz(returnedVector) to each momentum.
*/
ThreeVector<double> rotateToZ (Lorentz5Momentum& pTarget, Lorentz5Momentum& p1) {
ThreeVector<double> oldAxis = pTarget.vect().unit();
double ct = oldAxis.z(); double st = sqrt( 1.-sqr(ct) ); // cos,sin(theta)
double cp = oldAxis.x()/st; double sp = oldAxis.y()/st; // cos,sin(phi)
pTarget.setZ( pTarget.vect().mag() ); pTarget.setX( 0.*GeV ); pTarget.setY( 0.*GeV );
Lorentz5Momentum p1old = p1;
p1.setX( sp*p1old.x() - cp*p1old.y() );
p1.setY( ct*cp*p1old.x() + ct*sp*p1old.y() - st*p1old.z() );
p1.setZ( st*cp*p1old.x() + st*sp*p1old.y() + ct*p1old.z() );
return oldAxis;
}
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.
*/
FFMassiveInvertedTildeKinematics & operator=(const FFMassiveInvertedTildeKinematics &) = delete;
};
}
#endif /* HERWIG_FFMassiveInvertedTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.cc
@@ -1,232 +1,227 @@
// -*- C++ -*-
//
// FFMassiveTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FFMassiveTildeKinematics class.
//
#include "FFMassiveTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-FFMassiveTildeKinematics::FFMassiveTildeKinematics() {}
-
-FFMassiveTildeKinematics::~FFMassiveTildeKinematics() {}
-
IBPtr FFMassiveTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FFMassiveTildeKinematics::fullclone() const {
return new_ptr(*this);
}
// Matches Stephen Webster's thesis
bool FFMassiveTildeKinematics::doMap() {
Lorentz5Momentum emitter = realEmitterMomentum();
Lorentz5Momentum emission = realEmissionMomentum();
Lorentz5Momentum spectator = realSpectatorMomentum();
// Compute y
double y = emission*emitter / (emission*emitter + emission*spectator + emitter*spectator);
// Calculate the scale
Lorentz5Momentum pTot = emitter+emission+spectator;
Energy scale = pTot.m();
// masses
double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
double muj2 = sqr( realEmissionData()->hardProcessMass() / scale );
double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
double Muij2 = sqr( bornEmitterData()->hardProcessMass() / scale );
double Muk2 = sqr( bornSpectatorData()->hardProcessMass() / scale );
// Calculate the invariants
Energy2 Qijk = sqr(scale);
double sijkN = 0.5*( 1. - Muij2 - Muk2 + sqrt( sqr(1.-Muij2-Muk2) - 4.*Muij2*Muk2 ) );
double bar = 1. - mui2 - muj2 - muk2;
// Calculate Qij2
double QijN2 = sqr(emitter + emission)/Qijk;
// Calculate the scale factors, xk and xij
double lambdaK = 1. + (Muk2/sijkN);
double lambdaIJ = 1. + (Muij2/sijkN);
double fac1 = lambdaIJ*lambdaK + (muk2 - QijN2)/sijkN;
double xk =
( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*muk2/sijkN ) )
/ 2. / lambdaK ;
double xij = 1. - muk2*(1.-xk) / xk / sijkN;
// Calculate z = qi.nk / (qi+qj).nk from qi.qk and y
double l = Muk2 / (2.*xk*xij*sijkN);
double a = (xij*xk*sijkN/2.) - l*(bar*y + mui2 + muj2);
double b = (-emitter*spectator)/Qijk + l*(bar*y + 2.*mui2);
double z = -b/a;
// Calculate zi
double zi = emitter*spectator / ((emitter + emission)*spectator);
// Store the variables
subtractionParameters().resize(3);
subtractionParameters()[0] = y;
subtractionParameters()[1] = zi;
subtractionParameters()[2] = z;
// Calculate nij and nk from qi, q, qj
double L = QijN2/xij/xk/sijkN;
Lorentz5Momentum nij = (emitter + emission - L*spectator)/(xij - L*Muk2/xk/sijkN);
Lorentz5Momentum nk = (1./xk)*(spectator - Muk2*nij/(xk*sijkN));
// Calculate the born momenta from nij and nk
bornSpectatorMomentum() = nk + (Muk2/sijkN)*nij;
bornEmitterMomentum() = pTot - bornSpectatorMomentum();
bornEmitterMomentum().setMass( bornEmitterData()->hardProcessMass() );
bornEmitterMomentum().rescaleEnergy();
bornSpectatorMomentum().setMass( bornSpectatorData()->hardProcessMass() );
bornSpectatorMomentum().rescaleEnergy();
return true;
}
Energy FFMassiveTildeKinematics::lastPt() const {
Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m();
double y = subtractionParameters()[0];
double z = subtractionParameters()[2];
// masses
double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
double muj2 = sqr( realEmissionData()->hardProcessMass() / scale );
double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
Energy ret = scale * sqrt( y * (1.-mui2-muj2-muk2) * z*(1.-z) - sqr(1.-z)*mui2 - sqr(z)*muj2 );
return ret;
}
// Matches Stephen Webster's thesis
Energy FFMassiveTildeKinematics::lastPt(Lorentz5Momentum emitter,
Lorentz5Momentum emission,
Lorentz5Momentum spectator)const {
// Compute y
double y = emission*emitter / (emission*emitter
+ emission*spectator
+ emitter*spectator);
// Calculate the scale
Lorentz5Momentum pTot = emitter+emission+spectator;
Energy scale = pTot.m();
// masses
double mui2 = sqr( emitter.mass() / scale );
double muj2 = sqr( emission.mass() / scale );
double muk2 = sqr( spectator.mass() / scale );
// TODO: here we assume a gluon
bool isgluon= emitter.mass()==emission.mass();
double Muij2 = sqr(( isgluon?ZERO:max(emission.mass(),emitter.mass()) )/ scale );
double Muk2 = sqr( spectator.mass() / scale );
// Calculate the invariants
Energy2 Qijk = sqr(scale);
double sijkN = 0.5*( 1. - Muij2 - Muk2 + sqrt( sqr(1.-Muij2-Muk2) - 4.*Muij2*Muk2 ) );
double bar = 1. - mui2 - muj2 - muk2;
// Calculate Qij2
double QijN2 = sqr(emitter + emission)/Qijk;
// Calculate the scale factors, xk and xij
double lambdaK = 1. + (Muk2/sijkN);
double lambdaIJ = 1. + (Muij2/sijkN);
double fac1 = lambdaIJ*lambdaK + (muk2 - QijN2)/sijkN;
double xk =
( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*muk2/sijkN ) )
/ 2. / lambdaK ;
double xij = 1. - muk2*(1.-xk) / xk / sijkN;
// Calculate z = qi.nk / (qi+qj).nk from qi.qk and y
double l = Muk2 / (2.*xk*xij*sijkN);
double a = (xij*xk*sijkN/2.) - l*(bar*y + mui2 + muj2);
double b = (-emitter*spectator)/Qijk + l*(bar*y + 2.*mui2);
double z = -b/a;
Energy ret = scale * sqrt( z*(1.-z)*QijN2 - (1.-z)*mui2 - z*muj2 );
return ret;
}
// NOTE: bounds calculated at this step may be too loose
pair<double,double> FFMassiveTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
if(pt>hardPt) return make_pair(0.5,0.5);
Energy scale = (bornEmitterMomentum()+bornSpectatorMomentum()).m();
// masses
double mui2 = sqr( realEmitterData()->hardProcessMass() / scale );
double muj2 = sqr( realEmissionData()->hardProcessMass() / scale );
double muk2 = sqr( realSpectatorData()->hardProcessMass() / scale );
double zp = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) +
rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) *
sqrt( 1.-sqr(pt/hardPt) ) ) /
( 2.*sqr(1.-sqrt(muk2)) );
double zm = ( 1.+mui2-muj2+muk2-2.*sqrt(muk2) -
rootOfKallen(mui2,muj2,sqr(1.-sqrt(muk2))) *
sqrt( 1.-sqr(pt/hardPt) ) ) /
( 2.*sqr(1.-sqrt(muk2)) );
return make_pair(zm,zp);
}
double FFMassiveTildeKinematics::lastZ() const {
return subtractionParameters()[2];
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFMassiveTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void FFMassiveTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void FFMassiveTildeKinematics::Init() {
static ClassDocumentation<FFMassiveTildeKinematics> documentation
("FFMassiveTildeKinematics implements the 'tilde' kinematics for "
"a final-final subtraction dipole involving a massive particle.");
}
// *** 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<FFMassiveTildeKinematics,TildeKinematics>
describeHerwigFFMassiveTildeKinematics("Herwig::FFMassiveTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/FFMassiveTildeKinematics.h
@@ -1,148 +1,133 @@
// -*- C++ -*-
//
// FFMassiveTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFMassiveTildeKinematics_H
#define HERWIG_FFMassiveTildeKinematics_H
//
// This is the declaration of the FFMassiveTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Stephen Webster
*
* \brief FFMassiveTildeKinematics implements the 'tilde' kinematics for
* a final-final subtraction dipole.
*
*/
class FFMassiveTildeKinematics: public TildeKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- FFMassiveTildeKinematics();
-
- /**
- * The destructor.
- */
- virtual ~FFMassiveTildeKinematics();
- //@}
-
-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;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt ) const;
/**
* Return the pt associated to emitter emission and sppectator momentum.
*/
virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline T rootOfKallen (T a, T b, T c) const {
return sqrt( a*a + b*b + c*c - 2.*( a*b+a*c+b*c ) ); }
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.
*/
FFMassiveTildeKinematics & operator=(const FFMassiveTildeKinematics &) = delete;
};
}
#endif /* HERWIG_FFMassiveTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.cc
@@ -1,136 +1,132 @@
// -*- C++ -*-
//
// FILightInvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FILightInvertedTildeKinematics class.
//
#include "FILightInvertedTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-FILightInvertedTildeKinematics::FILightInvertedTildeKinematics() {}
-
-FILightInvertedTildeKinematics::~FILightInvertedTildeKinematics() {}
-
IBPtr FILightInvertedTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FILightInvertedTildeKinematics::fullclone() const {
return new_ptr(*this);
}
bool FILightInvertedTildeKinematics::doMap(const double * r) {
if ( ptMax() < ptCut() ) {
jacobian(0.0);
return false;
}
Lorentz5Momentum emitter = bornEmitterMomentum();
Lorentz5Momentum spectator = bornSpectatorMomentum();
double mapping = 1.0;
pair<Energy,double> ptz = generatePtZ(mapping,r);
if ( mapping == 0.0 ) {
jacobian(0.0);
return false;
}
Energy pt = ptz.first;
double z = ptz.second;
double y = sqr(pt/lastScale())/(z*(1.-z));
double x = 1./(1.+y);
if ( x < spectatorX() || x > 1. ||
z < 0. || z > 1. ) {
jacobian(0.0);
return false;
}
// This should (and does) have a factor of 1/x relative to
// the dipole shower jacobian.
mapping /= z*(1.-z);
jacobian(mapping*(sqr(lastScale())/sHat())/(16.*sqr(Constants::pi)));
double phi = 2.*Constants::pi*r[2];
Lorentz5Momentum kt
= getKt(spectator,emitter,pt,phi,true);
subtractionParameters().resize(2);
subtractionParameters()[0] = x;
subtractionParameters()[1] = z;
realEmitterMomentum() = z*emitter + (1.-z)*((1.-x)/x)*spectator + kt;
realEmissionMomentum() = (1.-z)*emitter + z*((1.-x)/x)*spectator - kt;
realSpectatorMomentum() = (1./x)*spectator;
realEmitterMomentum().setMass(ZERO);
realEmitterMomentum().rescaleEnergy();
realEmissionMomentum().setMass(ZERO);
realEmissionMomentum().rescaleEnergy();
realSpectatorMomentum().setMass(ZERO);
realSpectatorMomentum().rescaleEnergy();
return true;
}
Energy FILightInvertedTildeKinematics::lastPt() const {
Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum()));
double x = subtractionParameters()[0];
double z = subtractionParameters()[1];
return scale * sqrt(z*(1.-z)*(1.-x)/x);
}
double FILightInvertedTildeKinematics::lastZ() const {
return subtractionParameters()[1];
}
Energy FILightInvertedTildeKinematics::ptMax() const {
double x = spectatorX();
return sqrt((1.-x)/x)*lastScale()/2.;
}
pair<double,double> FILightInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax());
if(pt>hardPt) return make_pair(0.5,0.5);
double s = sqrt(1.-sqr(pt/hardPt));
return make_pair(0.5*(1.-s),0.5*(1.+s));
}
void FILightInvertedTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void FILightInvertedTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void FILightInvertedTildeKinematics::Init() {
static ClassDocumentation<FILightInvertedTildeKinematics> documentation
("FILightInvertedTildeKinematics inverts the final-initial tilde "
"kinematics.");
}
// *** 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<FILightInvertedTildeKinematics,InvertedTildeKinematics>
describeHerwigFILightInvertedTildeKinematics("Herwig::FILightInvertedTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/FILightInvertedTildeKinematics.h
@@ -1,138 +1,123 @@
// -*- C++ -*-
//
// FILightInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FILightInvertedTildeKinematics_H
#define HERWIG_FILightInvertedTildeKinematics_H
//
// This is the declaration of the FILightInvertedTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FILightInvertedTildeKinematics inverts the final-final tilde
* kinematics.
*
*/
class FILightInvertedTildeKinematics: public Herwig::InvertedTildeKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- FILightInvertedTildeKinematics();
-
- /**
- * The destructor.
- */
- virtual ~FILightInvertedTildeKinematics();
- //@}
-
-public:
-
/**
* Perform the mapping of the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the real
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap(const double *);
/**
* Return the pt associated to the last generated splitting.
*/
virtual Energy lastPt() const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
/**
* Return the upper bound on pt
*/
virtual Energy ptMax() const;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt = ZERO) 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.
*/
FILightInvertedTildeKinematics & operator=(const FILightInvertedTildeKinematics &) = delete;
};
}
#endif /* HERWIG_FILightInvertedTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/FILightTildeKinematics.cc
@@ -1,121 +1,116 @@
// -*- C++ -*-
//
// FILightTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FILightTildeKinematics class.
//
#include "FILightTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-FILightTildeKinematics::FILightTildeKinematics() {}
-
-FILightTildeKinematics::~FILightTildeKinematics() {}
-
IBPtr FILightTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FILightTildeKinematics::fullclone() const {
return new_ptr(*this);
}
bool FILightTildeKinematics::doMap() {
Lorentz5Momentum emitter = realEmitterMomentum();
Lorentz5Momentum emission = realEmissionMomentum();
Lorentz5Momentum spectator = realSpectatorMomentum();
double x =
(- emission*emitter + emission*spectator + emitter*spectator) /
(emitter*spectator + emission*spectator);
double z = emitter*spectator / (emitter*spectator + emission*spectator);
subtractionParameters().resize(2);
subtractionParameters()[0] = x;
subtractionParameters()[1] = z;
bornEmitterMomentum() = emitter+emission-(1.-x)*spectator;
bornSpectatorMomentum() = x*spectator;
bornEmitterMomentum().setMass(ZERO);
bornEmitterMomentum().rescaleEnergy();
bornSpectatorMomentum().setMass(ZERO);
bornSpectatorMomentum().rescaleEnergy();
return true;
}
Energy FILightTildeKinematics::lastPt() const {
Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum()));
double x = subtractionParameters()[0];
double z = subtractionParameters()[1];
return scale * sqrt(z*(1.-z)*(1.-x)/x);
}
Energy FILightTildeKinematics::lastPt(Lorentz5Momentum emitter,Lorentz5Momentum emission,Lorentz5Momentum spectator)const {
Energy2 scale = - (emitter+emission-spectator).m2();
double x =
(- emission*emitter + emission*spectator + emitter*spectator) /
(emitter*spectator + emission*spectator);
double z = emitter*spectator / (emitter*spectator + emission*spectator);
return sqrt( z*(1.-z)*(1.-x)/x*scale ) ;
}
pair<double,double> FILightTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
if(pt>hardPt) return make_pair(0.5,0.5);
double s = sqrt(1.-sqr(pt/hardPt));
return make_pair(0.5*(1.-s),0.5*(1.+s));
}
double FILightTildeKinematics::lastZ() const {
return subtractionParameters()[1];
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FILightTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void FILightTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void FILightTildeKinematics::Init() {
static ClassDocumentation<FILightTildeKinematics> documentation
("FILightTildeKinematics implements the 'tilde' kinematics for "
"a final-initial subtraction dipole.");
}
// *** 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<FILightTildeKinematics,TildeKinematics>
describeHerwigFILightTildeKinematics("Herwig::FILightTildeKinematics", "Herwig.so");
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,144 +1,129 @@
// -*- C++ -*-
//
// FILightTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt ) const;
/**
* Return the pt associated to emitter emission and sppectator momentum.
*/
virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) 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 &) = delete;
};
}
#endif /* HERWIG_FILightTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.cc
@@ -1,182 +1,178 @@
// -*- C++ -*-
//
// FIMassiveInvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FIMassiveInvertedTildeKinematics class.
//
#include "FIMassiveInvertedTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-FIMassiveInvertedTildeKinematics::FIMassiveInvertedTildeKinematics() {}
-
-FIMassiveInvertedTildeKinematics::~FIMassiveInvertedTildeKinematics() {}
-
IBPtr FIMassiveInvertedTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FIMassiveInvertedTildeKinematics::fullclone() const {
return new_ptr(*this);
}
bool FIMassiveInvertedTildeKinematics::doMap(const double * r) {
if ( ptMax() < ptCut() ) {
jacobian(0.0);
return false;
}
Lorentz5Momentum emitter = bornEmitterMomentum();
Lorentz5Momentum spectator = bornSpectatorMomentum();
double mapping = 1.0;
pair<Energy,double> ptz = generatePtZ(mapping,r);
if ( mapping == 0.0 ) {
jacobian(0.0);
return false;
}
Energy pt = ptz.first;
double z = ptz.second;
Energy2 mi2 = sqr(realEmitterData()->hardProcessMass());
Energy2 m2 = sqr(realEmissionData()->hardProcessMass());
Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass());
Energy2 scale=2.*emitter*spectator;
double y = (pt*pt+(1.-z)*mi2+z*m2-z*(1.-z)*Mi2) / (z*(1.-z)*scale);
double x = 1./(1.+y);
if ( x < spectatorX() ) {
jacobian(0.0);
return false;
}
// SW 05/12/2016: Checked this is correct
// This should appear to have a factor of 1/x relative
// to the dipole shower jacobian. It is cancelled by ratios of
// real and born cross sections in the units.
mapping /= z*(1.-z);
jacobian(mapping*(sqr(lastScale())/sHat())/(16.*sqr(Constants::pi)));
double phi = 2.*Constants::pi*r[2];
Lorentz5Momentum kt = getKt(spectator,emitter,pt,phi,true);
subtractionParameters().resize(2);
subtractionParameters()[0] = x;
subtractionParameters()[1] = z;
realEmitterMomentum() = z*emitter +
(sqr(pt)+mi2-z*z*Mi2)/(z*scale)*spectator + kt;
realEmissionMomentum() = (1.-z)*emitter +
(pt*pt+m2-sqr(1.-z)*Mi2)/((1.-z)*scale)*spectator - kt;
realSpectatorMomentum() = (1.+y)*spectator;
double mui2 = x*mi2/scale;
double mu2 = x*m2/scale;
double Mui2 = x*Mi2/scale;
double xp = 1. + Mui2 - sqr(sqrt(mui2)+sqrt(mu2));
double zm = .5*( 1.-x+Mui2+mui2-mu2 -
sqrt( sqr(1.-x+Mui2-mui2-mu2)-4.*mui2*mu2 ) ) / (1.-x+Mui2);
double zp = .5*( 1.-x+Mui2+mui2-mu2 +
sqrt( sqr(1.-x+Mui2-mui2-mu2)-4.*mui2*mu2 ) ) / (1.-x+Mui2);
if ( x > xp || z < zm || z > zp ) {
jacobian(0.0);
return false;
}
realEmitterMomentum().setMass(sqrt(mi2));
realEmitterMomentum().rescaleEnergy();
realEmissionMomentum().setMass(sqrt(m2));
realEmissionMomentum().rescaleEnergy();
realSpectatorMomentum().setMass(ZERO);
realSpectatorMomentum().rescaleEnergy();
return true;
}
Energy FIMassiveInvertedTildeKinematics::lastPt() const {
Energy2 mi2 = sqr(realEmitterData()->hardProcessMass());
Energy2 m2 = sqr(realEmissionData()->hardProcessMass());
Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass());
Energy2 scale = Mi2 - (realEmitterMomentum()+realEmissionMomentum()-realSpectatorMomentum()).m2();
double x = subtractionParameters()[0];
double z = subtractionParameters()[1];
return sqrt( z*(1.-z)*(1.-x)/x*scale -
((1.-z)*mi2+z*m2-z*(1.-z)*Mi2) );
}
double FIMassiveInvertedTildeKinematics::lastZ() const {
return subtractionParameters()[1];
}
Energy FIMassiveInvertedTildeKinematics::ptMax() const {
Energy2 mi2 = sqr(realEmitterData()->hardProcessMass());
Energy2 m2 = sqr(realEmissionData()->hardProcessMass());
Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass());
double x = spectatorX();
// s^star/x
Energy2 scale=2.*bornEmitterMomentum()*bornSpectatorMomentum();
Energy2 s = scale * (1.-x)/x + Mi2;
Energy ptmax = .5 * sqrt(s) * rootOfKallen( s/s, mi2/s, m2/s );
return ptmax > 0.*GeV ? ptmax : 0.*GeV;
}
pair<double,double> FIMassiveInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax());
if(pt>hardPt) return make_pair(0.5,0.5);
Energy2 mi2 = sqr(realEmitterData()->hardProcessMass());
Energy2 m2 = sqr(realEmissionData()->hardProcessMass());
Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass());
// s^star/x
Energy2 scale=2.*bornEmitterMomentum()*bornSpectatorMomentum();
Energy2 s = scale * (1.-spectatorX())/spectatorX() + Mi2;
double zm = .5*( 1.+(mi2-m2)/s - rootOfKallen(s/s,mi2/s,m2/s) *
sqrt( 1.-sqr(pt/hardPt) ) );
double zp = .5*( 1.+(mi2-m2)/s + rootOfKallen(s/s,mi2/s,m2/s) *
sqrt( 1.-sqr(pt/hardPt) ) );
return make_pair(zm, zp);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIMassiveInvertedTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void FIMassiveInvertedTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void FIMassiveInvertedTildeKinematics::Init() {
static ClassDocumentation<FIMassiveInvertedTildeKinematics> documentation
("FIMassiveInvertedTildeKinematics inverts the final-initial tilde "
"kinematics involving a massive particle.");
}
// *** 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<FIMassiveInvertedTildeKinematics,InvertedTildeKinematics>
describeHerwigFIMassiveInvertedTildeKinematics("Herwig::FIMassiveInvertedTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/FIMassiveInvertedTildeKinematics.h
@@ -1,147 +1,132 @@
// -*- C++ -*-
//
// FIMassiveInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FIMassiveInvertedTildeKinematics_H
#define HERWIG_FIMassiveInvertedTildeKinematics_H
//
// This is the declaration of the FIMassiveInvertedTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Martin Stoll
*
* \brief FIMassiveInvertedTildeKinematics inverts the final-final tilde
* kinematics.
*
*/
class FIMassiveInvertedTildeKinematics: public Herwig::InvertedTildeKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- FIMassiveInvertedTildeKinematics();
-
- /**
- * The destructor.
- */
- virtual ~FIMassiveInvertedTildeKinematics();
- //@}
-
-public:
-
/**
* Perform the mapping of the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the real
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap(const double *);
/**
* Return the pt associated to the last generated splitting.
*/
virtual Energy lastPt() const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
/**
* Return the upper bound on pt
*/
virtual Energy ptMax() const;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt = ZERO) const;
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline T rootOfKallen (T a, T b, T c) const {
return sqrt( a*a + b*b + c*c - 2.*( a*b+a*c+b*c ) ); }
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.
*/
FIMassiveInvertedTildeKinematics & operator=(const FIMassiveInvertedTildeKinematics &) = delete;
};
}
#endif /* HERWIG_FIMassiveInvertedTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.cc
@@ -1,149 +1,144 @@
// -*- C++ -*-
//
// FIMassiveTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FIMassiveTildeKinematics class.
//
#include "FIMassiveTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-FIMassiveTildeKinematics::FIMassiveTildeKinematics() {}
-
-FIMassiveTildeKinematics::~FIMassiveTildeKinematics() {}
-
IBPtr FIMassiveTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FIMassiveTildeKinematics::fullclone() const {
return new_ptr(*this);
}
bool FIMassiveTildeKinematics::doMap() {
Lorentz5Momentum emitter = realEmitterMomentum();
Lorentz5Momentum emission = realEmissionMomentum();
Lorentz5Momentum spectator = realSpectatorMomentum();
Energy2 mi2 = sqr(realEmitterData()->hardProcessMass());
Energy2 m2 = sqr(realEmissionData()->hardProcessMass());
Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass());
double x =
(- emission*emitter + emission*spectator + emitter*spectator +
0.5*(Mi2-mi2-m2)) /
(emitter*spectator + emission*spectator);
double z = emitter*spectator / (emitter*spectator + emission*spectator);
subtractionParameters().resize(2);
subtractionParameters()[0] = x;
subtractionParameters()[1] = z;
bornEmitterMomentum() = emitter+emission-(1.-x)*spectator;
bornSpectatorMomentum() = x*spectator;
bornEmitterMomentum().setMass(bornEmitterData()->hardProcessMass());
bornEmitterMomentum().rescaleEnergy();
bornSpectatorMomentum().setMass(bornSpectatorData()->hardProcessMass());
bornSpectatorMomentum().rescaleEnergy();
return true;
}
Energy FIMassiveTildeKinematics::lastPt() const {
Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass());
Energy2 mi2 = sqr(realEmitterData()->hardProcessMass());
Energy2 m2 = sqr(realEmissionData()->hardProcessMass());
Energy2 scale = Mi2 - (realEmitterMomentum()+realEmissionMomentum()-realSpectatorMomentum()).m2();
double x = subtractionParameters()[0];
double z = subtractionParameters()[1];
return sqrt( z*(1.-z)*(1.-x)/x*scale -
((1.-z)*mi2+z*m2-z*(1.-z)*Mi2) );
}
Energy FIMassiveTildeKinematics::lastPt(Lorentz5Momentum emitter,Lorentz5Momentum emission,Lorentz5Momentum spectator)const {
// g->QQ or Q -> Qg
Energy2 Mi2 = emitter.m()==emission.m()?0.*GeV2:max(emitter.m2(),emission.m2());
Energy2 mi2 = emitter.m2();
Energy2 m2 = emission.m2();
Energy2 scale = Mi2 - (emitter+emission-spectator).m2();
double x =
(- emission*emitter + emission*spectator + emitter*spectator +
0.5*(Mi2-mi2-m2)) /
(emitter*spectator + emission*spectator);
double z = emitter*spectator / (emitter*spectator + emission*spectator);
return sqrt( z*(1.-z)*(1.-x)/x*scale -
((1.-z)*mi2+z*m2-z*(1.-z)*Mi2) );
}
pair<double,double> FIMassiveTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
if(pt>hardPt) return make_pair(0.5,0.5);
Energy2 mi2 = sqr(realEmitterData()->hardProcessMass());
Energy2 m2 = sqr(realEmissionData()->hardProcessMass());
Energy2 Mi2 = sqr(bornEmitterData()->hardProcessMass());
// s^star/x
Energy2 scale=2.*bornEmitterMomentum()*bornSpectatorMomentum();
Energy2 s = scale * (1.-spectatorX())/spectatorX() + Mi2;
double zm = .5*( 1.+(mi2-m2)/s - rootOfKallen(s/s,mi2/s,m2/s) *
sqrt( 1.-sqr(pt/hardPt) ) );
double zp = .5*( 1.+(mi2-m2)/s + rootOfKallen(s/s,mi2/s,m2/s) *
sqrt( 1.-sqr(pt/hardPt) ) );
return make_pair(zm, zp);
}
double FIMassiveTildeKinematics::lastZ() const {
return subtractionParameters()[1];
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIMassiveTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void FIMassiveTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void FIMassiveTildeKinematics::Init() {
static ClassDocumentation<FIMassiveTildeKinematics> documentation
("FIMassiveTildeKinematics implements the 'tilde' kinematics for "
"a final-initial subtraction dipole involving a massive particle.");
}
// *** 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<FIMassiveTildeKinematics,TildeKinematics>
describeHerwigFIMassiveTildeKinematics("Herwig::FIMassiveTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/FIMassiveTildeKinematics.h
@@ -1,144 +1,129 @@
// -*- C++ -*-
//
// FIMassiveTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FIMassiveTildeKinematics_H
#define HERWIG_FIMassiveTildeKinematics_H
//
// This is the declaration of the FIMassiveTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Martin Stoll
*
* \brief FIMassiveTildeKinematics implements the 'tilde' kinematics for
* a final-initial subtraction dipole.
*
*/
class FIMassiveTildeKinematics: public TildeKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- FIMassiveTildeKinematics();
-
- /**
- * The destructor.
- */
- virtual ~FIMassiveTildeKinematics();
- //@}
-
-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 pt associated to emitter emission and sppectator momentum.
*/
virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt ) const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline T rootOfKallen (T a, T b, T c) const {
return sqrt( a*a + b*b + c*c - 2.*( a*b+a*c+b*c ) ); }
/** @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.
*/
FIMassiveTildeKinematics & operator=(const FIMassiveTildeKinematics &) = delete;
};
}
#endif /* HERWIG_FIMassiveTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.cc b/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.cc
--- a/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.cc
+++ b/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.cc
@@ -1,171 +1,169 @@
// -*- C++ -*-
//
// FlatInvertiblePhasespace.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FlatInvertibleLabframePhasespace class.
//
#include "FlatInvertibleLabframePhasespace.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig/Utilities/GSLBisection.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FlatInvertibleLabframePhasespace::FlatInvertibleLabframePhasespace()
: theLogSHat(false) {}
-FlatInvertibleLabframePhasespace::~FlatInvertibleLabframePhasespace() {}
-
IBPtr FlatInvertibleLabframePhasespace::clone() const {
return new_ptr(*this);
}
IBPtr FlatInvertibleLabframePhasespace::fullclone() const {
return new_ptr(*this);
}
double FlatInvertibleLabframePhasespace::invertTwoToNKinematics(const vector<Lorentz5Momentum>& momenta,
double* r) const {
double weight = 1.;
Energy finalstatemass = 0*GeV;
for ( vector<Lorentz5Momentum>::const_iterator p =
momenta.begin()+2; p != momenta.end(); ++p )
finalstatemass += p->mass();
Lorentz5Momentum pinitial = momenta[0]+momenta[1];
Energy2 sh = pinitial.m2();
double tau = sh/lastS();
Energy2 shmax = lastCuts().sHatMax();
Energy2 shmin = max(lastCuts().sHatMin(),sqr(finalstatemass));
if (theLogSHat) {
r[0] = log(sh/shmin)/log(shmax/shmin);
weight *= tau*log(shmax/shmin);
} else {
r[0] = (sh-shmin)/(shmax-shmin);
weight *= (shmax-shmin)/lastS();
}
double ltau = log(tau);
r[1] = 0.5 - pinitial.rapidity()/ltau;
weight *= -ltau;
vector<Lorentz5Momentum> Pcms = momenta;
Boost toCMS = pinitial.findBoostToCM();
for ( vector<Lorentz5Momentum>::iterator pit =
Pcms.begin(); pit != Pcms.end(); ++pit )
pit->boost(toCMS);
weight *= FlatInvertiblePhasespace::invertTwoToNKinematics(Pcms, r+2);
return weight;
}
double FlatInvertibleLabframePhasespace::generateTwoToNKinematics(const double* r,
vector<Lorentz5Momentum>& momenta) {
double weight = 1.;
Energy finalstatemass = 0*GeV;
for ( vector<Lorentz5Momentum>::const_iterator p =
momenta.begin()+2; p != momenta.end(); ++p )
finalstatemass += p->mass();
Energy beamenergy = sqrt(lastS())/2.;
Energy2 shmax = lastCuts().sHatMax();
Energy2 shmin = max(lastCuts().sHatMin(),sqr(finalstatemass));
Energy2 sh;
double tau;
if (theLogSHat) {
sh = shmin*pow(shmax/shmin, r[0]);
tau = sh/lastS();
weight *= tau*log(shmax/shmin);
} else {
sh = r[0]*(shmax-shmin)+shmin;
tau = sh/lastS();
weight *= (shmax-shmin)/lastS();
}
double ltau = log(tau);
double y = ltau*(0.5 - r[1]);
weight *= -ltau;
double x1 = sqrt(tau)*exp(y);
double x2 = sqrt(tau)*exp(-y);
momenta[0] = Lorentz5Momentum(0*GeV,0*GeV,+x1*beamenergy,x1*beamenergy);
momenta[1] = Lorentz5Momentum(0*GeV,0*GeV,-x2*beamenergy,x2*beamenergy);
lastXCombPtr()->lastX1X2(make_pair(x1,x2));
lastXCombPtr()->lastSHat(sh);
weight *= FlatInvertiblePhasespace::generateTwoToNKinematics(r+2, momenta);
// find boost to the relevant partonic frame note final state kinematics are
// always generated in the CMS for this phase space algorithm
Boost boostinitial = (momenta[0]+momenta[1]).findBoostToCM();
for ( vector<Lorentz5Momentum>::iterator pit =
momenta.begin()+2; pit != momenta.end(); ++pit )
pit->boost(-boostinitial);
return weight;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FlatInvertibleLabframePhasespace::persistentOutput(PersistentOStream & os) const {
os << theLogSHat;
}
void FlatInvertibleLabframePhasespace::persistentInput(PersistentIStream & is, int) {
is >> theLogSHat;
}
// *** 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<FlatInvertibleLabframePhasespace,MatchboxPhasespace>
describeHerwigFlatInvertibleLabframePhasespace("Herwig::FlatInvertibleLabframePhasespace", "Herwig.so");
void FlatInvertibleLabframePhasespace::Init() {
static ClassDocumentation<FlatInvertibleLabframePhasespace> documentation
("FlatInvertibleLabframePhasespace implements flat, invertible phase space generation in the lab frame.");
static Switch<FlatInvertibleLabframePhasespace,bool> interfaceLogSHat
("LogSHat",
"Generate a flat distribution in \\f$\\log(\\hat{s})\\f$.",
&FlatInvertibleLabframePhasespace::theLogSHat, false, false, false);
static SwitchOption interfaceLogSHatYes
(interfaceLogSHat,
"Yes", "Generate flat in \\f$\\log(\\hat{s})\\f$", true);
static SwitchOption interfaceLogSHatNo
(interfaceLogSHat,
"No", "Generate flat in \\f$\\hat{s}\\f$", false);
interfaceLogSHat.rank(-1);
}
diff --git a/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.h b/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.h
--- a/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.h
+++ b/MatrixElement/Matchbox/Phasespace/FlatInvertibleLabframePhasespace.h
@@ -1,152 +1,144 @@
// -*- C++ -*-
//
// FlatInvertiblePhasespaceLabFrame.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_FlatInvertibleLabframePhasespace_H
#define Herwig_FlatInvertibleLabframePhasespace_H
//
// This is the declaration of the FlatInvertibleLabframePhasespace class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Michael Rauch
*
* \brief FlatInvertibleLabframePhasespace implements flat, invertible phase space generation in the lab frame
*
*/
class FlatInvertibleLabframePhasespace: public FlatInvertiblePhasespace {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FlatInvertibleLabframePhasespace();
- /**
- * The destructor.
- */
- virtual ~FlatInvertibleLabframePhasespace();
- //@}
-
public:
/**
* Generate a phase space point and return its weight.
*/
virtual double generateTwoToNKinematics(const double*,
vector<Lorentz5Momentum>& momenta);
/**
* Return the number of random numbers required to produce a given
* multiplicity final state.
*/
virtual int nDimPhasespace(int nFinal) const {
if ( nFinal == 1 )
return 3;
return 3*nFinal - 2;
}
public:
/**
* Return true, if this phasespace generator will generate incoming
* partons itself.
*/
virtual bool haveX1X2() const { return true; }
/**
* Return true, if this phase space generator expects
* the incoming partons in their center-of-mass system
*/
virtual bool wantCMS() const { return false; }
/**
* Invert the given phase space point to the random numbers which
* would have generated it.
*/
virtual double invertTwoToNKinematics(const vector<Lorentz5Momentum>& momenta,
double* r) const;
private:
/**
* True if SHat should be generated flat in log(SHat/S),
* false if SHat should be generated flat in SHat.
*/
bool theLogSHat;
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.
*/
FlatInvertibleLabframePhasespace & operator=(const FlatInvertibleLabframePhasespace &) = delete;
};
}
#endif /* Herwig_FlatInvertiblePhasespace_H */
diff --git a/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.cc b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.cc
--- a/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.cc
+++ b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.cc
@@ -1,304 +1,299 @@
// -*- C++ -*-
//
// FlatInvertiblePhasespace.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FlatInvertiblePhasespace class.
//
#include "FlatInvertiblePhasespace.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig/Utilities/GSLBisection.h"
#include "ThePEG/Cuts/Cuts.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-FlatInvertiblePhasespace::FlatInvertiblePhasespace() {}
-
-FlatInvertiblePhasespace::~FlatInvertiblePhasespace() {}
-
IBPtr FlatInvertiblePhasespace::clone() const {
return new_ptr(*this);
}
IBPtr FlatInvertiblePhasespace::fullclone() const {
return new_ptr(*this);
}
double FlatInvertiblePhasespace::bisect(double v, double n,
double target, double maxLevel) const {
if ( v != 0.0 && v != 1.0 ) {
double level = 0;
double left = 0;
double right = 1;
double checkV = -1.;
double u = -1;
while ( level < maxLevel ) {
u = (left+right)*pow(0.5,level+1.);
checkV =
pow(u,n+1.)*(n+2.-(n+1.)*u);
if ( log10(abs(1.-checkV/v)) <= target )
break;
left *= 2.;
right *= 2.;
if ( v <= checkV ) {
right -= 1.;
++level;
}
if ( v > checkV ) {
left += 1.;
++level;
}
}
return u;
}
return v;
}
double FlatInvertiblePhasespace::generateIntermediates(vector<Energy>& K,
const double* r) const {
size_t n = K.size() + 1;
for ( size_t i = 2; i <= n-1; ++i ) {
double u = bisect(r[i-2],n-1-i);
K[i-1] = sqrt(u*sqr(K[i-2]));
}
int kap = K.size() + 1;
return flatWeights(kap);
}
double FlatInvertiblePhasespace::invertIntermediates(const vector<Energy>& K,
double* r) const {
size_t n = K.size() + 1;
for ( size_t i = 2; i <= n-1; ++i ) {
double u = sqr(K[i-1]/K[i-2]);
r[i-2] = (n+1-i)*pow(u,(double)(n-i)) - (n-i)*pow(u,(double)(n+1-i));
}
int kap = K.size() + 1;
return flatWeights(kap);
}
double FlatInvertiblePhasespace::generateIntermediates(vector<Energy>& M,
const vector<Energy>& m,
const double* r) const {
size_t n = M.size() + 1;
vector<Energy> K = M;
for ( size_t i = 1; i <= n; ++i )
K[0] -= m[i-1];
double w0 = generateIntermediates(K,r);
M = K;
for ( size_t i = 1; i <= n-1; ++i ) {
for ( size_t k = i; k <= n; ++k )
M[i-1] += m[k-1];
}
double weight = 8.*w0*rho(M[n-2],m[n-1],m[n-2]);
for ( size_t i = 2; i <= n-1; ++i ) {
weight *=
(rho(M[i-2],M[i-1],m[i-2])/rho(K[i-2],K[i-1],ZERO)) * (M[i-1]/K[i-1]);
}
weight *= pow(K[0]/M[0],2.*n-4.);
return weight;
}
double FlatInvertiblePhasespace::invertIntermediates(const vector<Energy>& M,
const vector<Energy>& m,
double* r) const {
size_t n = M.size() + 1;
vector<Energy> K = M;
for ( size_t i = 1; i <= n-1; ++i ) {
for ( size_t k = i; k <= n; ++k )
K[i-1] -= m[k-1];
}
double w0 = invertIntermediates(K,r);
double weight = 8.*w0*rho(M[n-2],m[n-1],m[n-2]);
for ( size_t i = 2; i <= n-1; ++i ) {
weight *=
(rho(M[i-2],M[i-1],m[i-2])/rho(K[i-2],K[i-1],ZERO)) * (M[i-1]/K[i-1]);
}
weight *= pow(K[0]/M[0],2.*n-4.);
return weight;
}
double FlatInvertiblePhasespace::generateKinematics(vector<Lorentz5Momentum>& P,
Energy Ecm,
const double* r) const {
vector<Energy> m;
for ( vector<Lorentz5Momentum>::const_iterator p =
P.begin() + 2; p != P.end(); ++p )
m.push_back(p->mass());
size_t n = P.size() - 2;
vector<Energy> M(n-1);
M[0] = Ecm;
double weight = generateIntermediates(M,m,r);
M.push_back(m.back());
Lorentz5Momentum Q(M[0]);
Lorentz5Momentum nextQ;
for ( size_t i = 2; i <= n; ++i ) {
Energy q = 4.*M[i-2]*rho(M[i-2],M[i-1],m[i-2]);
double c = 2.*r[n-6+2*i]-1.;
double s = sqrt(1.-sqr(c));
double phi = 2.*Constants::pi*r[n-5+2*i];
double cphi = cos(phi);
double sphi = sqrt(1.-sqr(cphi));
if ( phi > Constants::pi )
sphi = -sphi;
P[i].setX(q*cphi*s);
P[i].setY(q*sphi*s);
P[i].setZ(q*c);
P[i].rescaleEnergy();
P[i].boost(Q.boostVector());
P[i].rescaleEnergy();
nextQ = Q - P[i];
nextQ.setMass(M[i-1]);
nextQ.rescaleEnergy();
Q = nextQ;
}
P.back() = Q;
return weight;
}
double FlatInvertiblePhasespace::invertKinematics(const vector<Lorentz5Momentum>& P,
Energy Ecm,
double* r) const {
vector<Energy> m;
for ( vector<Lorentz5Momentum>::const_iterator p =
P.begin() + 2; p != P.end(); ++p )
m.push_back(p->mass());
size_t n = P.size() - 2;
vector<Energy> M(n-1);
M[0] = Ecm;
vector<Lorentz5Momentum> Q(n-1);
Q[0] = Lorentz5Momentum(M[0]);
for ( size_t i = 2; i <= n-1; ++i ) {
for ( size_t k = i; k <= n; ++k )
Q[i-1] += P[k+1];
M[i-1] = Q[i-1].m();
}
double weight = invertIntermediates(M,m,r);
for ( size_t i = 2; i <= n; ++i ) {
Lorentz5Momentum p = P[i];
p.boost(-Q[i-2].boostVector());
r[n-6+2*i] = (p.cosTheta()+1.)/2.;
double phi = p.phi();
if ( phi < 0. )
phi = 2.*Constants::pi + phi;
r[n-5+2*i] = phi/(2.*Constants::pi);
}
return weight;
}
double FlatInvertiblePhasespace::generateTwoToNKinematics(const double* r,
vector<Lorentz5Momentum>& momenta) {
double weight = generateKinematics(momenta,sqrt(lastXCombPtr()->lastSHat()),r);
return weight;
}
long double FlatInvertiblePhasespace::flatWeights(int k) const{
using Constants::pi;
if(k<2) { return -1;
} else return pow((pi/2),(k-1)) * pow((2*pi),(4-3*k))/factorial(k-1)/factorial(k-2);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FlatInvertiblePhasespace::persistentOutput(PersistentOStream &) const {}
void FlatInvertiblePhasespace::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<FlatInvertiblePhasespace,MatchboxPhasespace>
describeHerwigFlatInvertiblePhasespace("Herwig::FlatInvertiblePhasespace", "Herwig.so");
void FlatInvertiblePhasespace::Init() {
static ClassDocumentation<FlatInvertiblePhasespace> documentation
("FlatInvertiblePhasespace implements flat, invertible phase space generation.");
}
diff --git a/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h
--- a/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h
+++ b/MatrixElement/Matchbox/Phasespace/FlatInvertiblePhasespace.h
@@ -1,204 +1,189 @@
// -*- C++ -*-
//
// FlatInvertiblePhasespace.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_FlatInvertiblePhasespace_H
#define Herwig_FlatInvertiblePhasespace_H
//
// This is the declaration of the FlatInvertiblePhasespace class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief FlatInvertiblePhasespace implements flat, invertible phase space generation.
*
*/
class FlatInvertiblePhasespace: public MatchboxPhasespace {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- FlatInvertiblePhasespace();
-
- /**
- * The destructor.
- */
- virtual ~FlatInvertiblePhasespace();
- //@}
-
-public:
-
/**
* Generate a phase space point and return its weight.
*/
virtual double generateTwoToNKinematics(const double*,
vector<Lorentz5Momentum>& momenta);
/**
* Return the number of random numbers required to produce a given
* multiplicity final state.
*/
virtual int nDimPhasespace(int nFinal) const {
if ( nFinal == 1 )
return 1;
return 3*nFinal - 4;
}
public:
/**
* Return true, if this phase space generator is invertible
*/
virtual bool isInvertible() const { return true; }
/**
* Invert the given phase space point to the random numbers which
* would have generated it.
*/
virtual double invertTwoToNKinematics(const vector<Lorentz5Momentum>& momenta,
double* r) const {
return invertKinematics(momenta,(momenta[0]+momenta[1]).m(),r);
}
private:
/**
* Solve v = (n+2) * u^(n+1) - (n+1) * u^(n+2) for u
*/
double bisect(double v, double n,
double target = -16., double maxLevel = 80.) const;
/**
* Return rho
*/
double rho(Energy M, Energy N, Energy m) const {
return sqrt((sqr(M)-sqr(N+m))*(sqr(M)-sqr(N-m)))/(8.*sqr(M));
}
/**
* Generate intermediate masses for a massless final state
*/
double generateIntermediates(vector<Energy>& K,
const double* r) const;
/**
* Invert intermediate masses for a massless final state
*/
double invertIntermediates(const vector<Energy>& K,
double* r) const;
/**
* Generate intermediate masses for a massive final state
*/
double generateIntermediates(vector<Energy>& M,
const vector<Energy>& m,
const double* r) const;
/**
* Invert intermediate masses for a massive final state
*/
double invertIntermediates(const vector<Energy>& M,
const vector<Energy>& m,
double* r) const;
/**
* Generate momenta in the CMS
*/
double generateKinematics(vector<Lorentz5Momentum>& P,
Energy Ecm,
const double* r) const;
/**
* Invert momenta in the CMS
*/
double invertKinematics(const vector<Lorentz5Momentum>& P,
Energy Ecm,
double* r) const;
/**
* Return the appropriate phase space weight,
* Eq. 11 in 1308.2922
* with the factor (2 pi)^4/(2 pi)^(3n) included
* and the SHat of the process divided out to have everything expressed in the units of the ThePEG conventions, i.e.
* without the Q^2 factor
*/
long double flatWeights(int n) 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.
*/
FlatInvertiblePhasespace & operator=(const FlatInvertiblePhasespace &) = delete;
};
}
#endif /* Herwig_FlatInvertiblePhasespace_H */
diff --git a/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.cc
@@ -1,150 +1,145 @@
// -*- C++ -*-
//
// IFLightInvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 IFLightInvertedTildeKinematics class.
//
#include "IFLightInvertedTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/EventGenerator.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-IFLightInvertedTildeKinematics::IFLightInvertedTildeKinematics() {}
-
-IFLightInvertedTildeKinematics::~IFLightInvertedTildeKinematics() {}
-
IBPtr IFLightInvertedTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IFLightInvertedTildeKinematics::fullclone() const {
return new_ptr(*this);
}
bool IFLightInvertedTildeKinematics::doMap(const double * r) {
if ( ptMax() < ptCut() ) {
jacobian(0.0);
return false;
}
Lorentz5Momentum emitter = bornEmitterMomentum();
Lorentz5Momentum spectator = bornSpectatorMomentum();
double mapping = 1.0;
pair<Energy,double> ptz = generatePtZ(mapping,r);
if ( mapping == 0.0 ) {
jacobian(0.0);
return false;
}
Energy pt = ptz.first;
double z = ptz.second;
double ratio = sqr(pt/lastScale());
double rho = 1. - 4.*ratio*z*(1.-z) / sqr(1. - z + ratio);
if ( rho < 0. ) {
jacobian(0.0);
return false;
}
double x = 0.5*(1./ratio)*(1.-z+ratio)*(1.-sqrt(rho));
double u = 0.5*(1./(1.-z))*(1.-z+ratio)*(1.-sqrt(rho));
if ( x < emitterX() || x > 1. ||
u < 0. || u > 1. ) {
jacobian(0.0);
return false;
}
// This jacobian is (1/x^2)*dx*du
mapping *= (1.-x)/((1.-z)*(z*(1.-z)+sqr(x-z)));
jacobian(mapping*(sqr(lastScale())/sHat())/(16.*sqr(Constants::pi)));
double phi = 2.*Constants::pi*r[2];
Lorentz5Momentum kt = getKt(emitter,spectator,pt,phi,true);
subtractionParameters().resize(2);
subtractionParameters()[0] = x;
subtractionParameters()[1] = u;
realEmitterMomentum() = (1./x)*emitter;
realEmissionMomentum() = ((1.-x)*(1.-u)/x)*emitter + u*spectator + kt;
realSpectatorMomentum() = ((1.-x)*u/x)*emitter + (1.-u)*spectator - kt;
realEmitterMomentum().setMass(ZERO);
realEmitterMomentum().rescaleEnergy();
realEmissionMomentum().setMass(ZERO);
realEmissionMomentum().rescaleEnergy();
realSpectatorMomentum().setMass(ZERO);
realSpectatorMomentum().rescaleEnergy();
return true;
}
Energy IFLightInvertedTildeKinematics::lastPt() const {
Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum()));
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
return scale * sqrt(u*(1.-u)*(1.-x)/x);
}
Energy IFLightInvertedTildeKinematics::ptMax() const {
double x = emitterX();
return sqrt((1.-x)/x)*lastScale()/2.;
}
pair<double,double> IFLightInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax());
if(pt>hardPt) return make_pair(0.5,0.5);
double s = sqrt(1.-sqr(pt/hardPt));
double x = emitterX();
return make_pair(0.5*(1.+x-(1.-x)*s),0.5*(1.+x+(1.-x)*s));
}
double IFLightInvertedTildeKinematics::lastZ() const {
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
return 1. - (1.-x)*(1.-u);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFLightInvertedTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void IFLightInvertedTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void IFLightInvertedTildeKinematics::Init() {
static ClassDocumentation<IFLightInvertedTildeKinematics> documentation
("IFLightInvertedTildeKinematics inverts the initial-final tilde "
"kinematics.");
}
// *** 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<IFLightInvertedTildeKinematics,InvertedTildeKinematics>
describeHerwigIFLightInvertedTildeKinematics("Herwig::IFLightInvertedTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/IFLightInvertedTildeKinematics.h
@@ -1,138 +1,123 @@
// -*- C++ -*-
//
// IFLightInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IFLightInvertedTildeKinematics_H
#define HERWIG_IFLightInvertedTildeKinematics_H
//
// This is the declaration of the IFLightInvertedTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief IFLightInvertedTildeKinematics inverts the final-final tilde
* kinematics.
*
*/
class IFLightInvertedTildeKinematics: public Herwig::InvertedTildeKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- IFLightInvertedTildeKinematics();
-
- /**
- * The destructor.
- */
- virtual ~IFLightInvertedTildeKinematics();
- //@}
-
-public:
-
/**
* Perform the mapping of the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the real
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap(const double *);
/**
* Return the pt associated to the last generated splitting.
*/
virtual Energy lastPt() const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
/**
* Return the upper bound on pt
*/
virtual Energy ptMax() const;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt = ZERO) 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.
*/
IFLightInvertedTildeKinematics & operator=(const IFLightInvertedTildeKinematics &) = delete;
};
}
#endif /* HERWIG_IFLightInvertedTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/IFLightTildeKinematics.cc
@@ -1,123 +1,118 @@
// -*- C++ -*-
//
// IFLightTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 IFLightTildeKinematics class.
//
#include "IFLightTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-IFLightTildeKinematics::IFLightTildeKinematics() {}
-
-IFLightTildeKinematics::~IFLightTildeKinematics() {}
-
IBPtr IFLightTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IFLightTildeKinematics::fullclone() const {
return new_ptr(*this);
}
bool IFLightTildeKinematics::doMap() {
Lorentz5Momentum emitter = realEmitterMomentum();
Lorentz5Momentum emission = realEmissionMomentum();
Lorentz5Momentum spectator = realSpectatorMomentum();
double x =
(- emission*spectator + emitter*spectator + emitter*emission) /
(emitter*emission + emitter*spectator);
double u = emitter*emission / (emitter*emission + emitter*spectator);
subtractionParameters().resize(2);
subtractionParameters()[0] = x;
subtractionParameters()[1] = u;
bornEmitterMomentum() = x*emitter;
bornSpectatorMomentum() = spectator + emission - (1.-x)*emitter;
bornEmitterMomentum().setMass(ZERO);
bornEmitterMomentum().rescaleEnergy();
bornSpectatorMomentum().setMass(ZERO);
bornSpectatorMomentum().rescaleEnergy();
return true;
}
Energy IFLightTildeKinematics::lastPt() const {
Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum()));
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
return scale * sqrt(u*(1.-u)*(1.-x)/x);
}
Energy IFLightTildeKinematics::lastPt(Lorentz5Momentum emitter,Lorentz5Momentum emission,Lorentz5Momentum spectator)const {
double x =
(- emission*spectator + emitter*spectator + emitter*emission) /
(emitter*emission + emitter*spectator);
double u = emitter*emission / (emitter*emission + emitter*spectator);
Energy scale = sqrt(2.*(emission*emitter-emission*spectator+emitter*spectator));
return scale * sqrt(u*(1.-u)*(1.-x)/x);
}
pair<double,double> IFLightTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
if(pt>hardPt) return make_pair(0.5,0.5);
double s = sqrt(1.-sqr(pt/hardPt));
double x = emitterX();
return make_pair(0.5*(1.+x-(1.-x)*s),0.5*(1.+x+(1.-x)*s));
}
double IFLightTildeKinematics::lastZ() const {
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
return 1. - (1.-x)*(1.-u);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFLightTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void IFLightTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void IFLightTildeKinematics::Init() {
static ClassDocumentation<IFLightTildeKinematics> documentation
("IFLightTildeKinematics implements the 'tilde' kinematics for "
"a initial-final subtraction dipole.");
}
// *** 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<IFLightTildeKinematics,TildeKinematics>
describeHerwigIFLightTildeKinematics("Herwig::IFLightTildeKinematics", "Herwig.so");
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,146 +1,131 @@
// -*- C++ -*-
//
// IFLightTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 pt associated to emitter emission and sppectator momentum.
*/
virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt ) 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 &) = delete;
};
}
#endif /* HERWIG_IFLightTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.cc
@@ -1,165 +1,160 @@
// -*- C++ -*-
//
// IFMassiveInvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 IFMassiveInvertedTildeKinematics class.
//
#include "IFMassiveInvertedTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/EventGenerator.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-IFMassiveInvertedTildeKinematics::IFMassiveInvertedTildeKinematics() {}
-
-IFMassiveInvertedTildeKinematics::~IFMassiveInvertedTildeKinematics() {}
-
IBPtr IFMassiveInvertedTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IFMassiveInvertedTildeKinematics::fullclone() const {
return new_ptr(*this);
}
bool IFMassiveInvertedTildeKinematics::doMap(const double * r) {
if ( ptMax() < ptCut() ) {
jacobian(0.0);
return false;
}
// Compute dipole scale
Lorentz5Momentum emitter = bornEmitterMomentum();
Lorentz5Momentum spectator = bornSpectatorMomentum();
Energy2 scale = 2.*(spectator*emitter);
// Generate pt and z
double mapping = 1.0;
pair<Energy,double> ptz = generatePtZ(mapping,r);
if ( mapping == 0.0 ){
jacobian(0.0);
return false;
}
Energy pt = ptz.first;
double z = ptz.second;
// Compute x and u
double ratio = sqr(pt)/scale;
double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale;
double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio);
double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho));
double u = x*ratio / (1.-z);
// Following Catani-Seymour paper
double muk2CS = x*muk2;
double up = (1.-x) /
( 1.-x + muk2CS );
if ( x < emitterX() || x > 1. ||
u < 0. || u > up ) {
jacobian(0.0);
return false;
}
// Store x and u
subtractionParameters().resize(2);
subtractionParameters()[0] = x;
subtractionParameters()[1] = u;
// jac = sajk*(1./x^2)*dx*du
// Note - lastScale() is not equal to scale!!!!!!!
double jac = u/x/(u + x - 2.*u*x*(1.-muk2))*scale/sqr(pt);
mapping *= jac;
jacobian( mapping*(sqr(lastScale())/sHat()) / (16.*sqr(Constants::pi)) );
// Compute the new momenta
double phi = 2.*Constants::pi*r[2];
Lorentz5Momentum kt = getKt(emitter,spectator,pt,phi,true);
realEmitterMomentum() = (1./x)*emitter;
realEmissionMomentum() = ((1.-x)*(1.-u)/x - 2.*u*muk2)*emitter + u*spectator + kt;
realSpectatorMomentum() = ((1.-x)*u/x + 2.*u*muk2)*emitter + (1.-u)*spectator - kt;
realEmitterMomentum().setMass(ZERO);
realEmitterMomentum().rescaleEnergy();
realEmissionMomentum().setMass(ZERO);
realEmissionMomentum().rescaleEnergy();
realSpectatorMomentum().setMass(bornSpectatorData()->hardProcessMass());
realSpectatorMomentum().rescaleEnergy();
return true;
}
Energy IFMassiveInvertedTildeKinematics::lastPt() const {
Energy2 scale = 2.*(bornEmitterMomentum()*bornSpectatorMomentum());
double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale;
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
return sqrt(scale * ( u*(1.-u)*(1.-x)/x - u*u*muk2 ));
}
double IFMassiveInvertedTildeKinematics::lastZ() const {
Energy2 scale = 2.*(bornEmitterMomentum()*bornSpectatorMomentum());
double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale;
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
return u + x + u*x*(muk2-1.);
}
Energy IFMassiveInvertedTildeKinematics::ptMax() const {
double xe = emitterX();
Energy2 scale = 2.*(bornEmitterMomentum()*bornSpectatorMomentum());
Energy2 A = scale*(1.-xe)/xe;
Energy2 mk2 = sqr(bornSpectatorData()->hardProcessMass());
return 0.5*A/sqrt(mk2+A);
}
pair<double,double> IFMassiveInvertedTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
hardPt = hardPt == ZERO ? ptMax() : min(hardPt,ptMax());
if(pt>hardPt) return make_pair(0.5,0.5);
double s = sqrt(1.-sqr(pt/hardPt));
double xe = emitterX();
return make_pair(0.5*(1.+xe-(1.-xe)*s),0.5*(1.+xe+(1.-xe)*s));
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFMassiveInvertedTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void IFMassiveInvertedTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void IFMassiveInvertedTildeKinematics::Init() {
static ClassDocumentation<IFMassiveInvertedTildeKinematics> documentation
("IFMassiveInvertedTildeKinematics inverts the initial-final tilde "
"kinematics involving a massive particle.");
}
// *** 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<IFMassiveInvertedTildeKinematics,InvertedTildeKinematics>
describeHerwigIFMassiveInvertedTildeKinematics("Herwig::IFMassiveInvertedTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/IFMassiveInvertedTildeKinematics.h
@@ -1,138 +1,123 @@
// -*- C++ -*-
//
// IFMassiveInvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IFMassiveInvertedTildeKinematics_H
#define HERWIG_IFMassiveInvertedTildeKinematics_H
//
// This is the declaration of the IFMassiveInvertedTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Martin Stoll
*
* \brief IFMassiveInvertedTildeKinematics inverts the final-final tilde
* kinematics.
*
*/
class IFMassiveInvertedTildeKinematics: public Herwig::InvertedTildeKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- IFMassiveInvertedTildeKinematics();
-
- /**
- * The destructor.
- */
- virtual ~IFMassiveInvertedTildeKinematics();
- //@}
-
-public:
-
/**
* Perform the mapping of the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the real
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap(const double *);
/**
* Return the pt associated to the last generated splitting.
*/
virtual Energy lastPt() const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() const;
/**
* Return the upper bound on pt
*/
virtual Energy ptMax() const;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt = ZERO) 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.
*/
IFMassiveInvertedTildeKinematics & operator=(const IFMassiveInvertedTildeKinematics &) = delete;
};
}
#endif /* HERWIG_IFMassiveInvertedTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.cc
@@ -1,124 +1,119 @@
// -*- C++ -*-
//
// IFMassiveTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 IFMassiveTildeKinematics class.
//
#include "IFMassiveTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-IFMassiveTildeKinematics::IFMassiveTildeKinematics() {}
-
-IFMassiveTildeKinematics::~IFMassiveTildeKinematics() {}
-
IBPtr IFMassiveTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IFMassiveTildeKinematics::fullclone() const {
return new_ptr(*this);
}
bool IFMassiveTildeKinematics::doMap() {
Lorentz5Momentum emitter = realEmitterMomentum();
Lorentz5Momentum emission = realEmissionMomentum();
Lorentz5Momentum spectator = realSpectatorMomentum();
double x =
(- emission*spectator + emitter*spectator + emitter*emission) /
(emitter*emission + emitter*spectator);
double u = emitter*emission / (emitter*emission + emitter*spectator);
subtractionParameters().resize(2);
subtractionParameters()[0] = x;
subtractionParameters()[1] = u;
bornEmitterMomentum() = x*emitter;
bornSpectatorMomentum() = spectator + emission - (1.-x)*emitter;
bornEmitterMomentum().setMass(ZERO);
bornEmitterMomentum().rescaleEnergy();
bornSpectatorMomentum().setMass(bornSpectatorData()->hardProcessMass());
bornSpectatorMomentum().rescaleEnergy();
return true;
}
Energy IFMassiveTildeKinematics::lastPt() const {
Energy2 scale = 2.*(realEmissionMomentum()*realEmitterMomentum()
-realEmissionMomentum()*realSpectatorMomentum()
+realEmitterMomentum()*realSpectatorMomentum());
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale;
return sqrt(scale * ( u*(1.-u)*(1.-x)/x - u*u*muk2 ));
}
Energy IFMassiveTildeKinematics::lastPt(Lorentz5Momentum emitter,Lorentz5Momentum emission,Lorentz5Momentum spectator)const {
Energy2 scale = 2.*(emission*emitter-emission*spectator+emitter*spectator);
double x = 0.5*scale / (emitter*emission + emitter*spectator);
double u = emitter*emission / (emitter*emission + emitter*spectator);
double muk2 = sqr(spectator.mass())/scale;
return sqrt(scale * ( u*(1.-u)*(1.-x)/x - u*u*muk2 ));
}
pair<double,double> IFMassiveTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
if(pt>hardPt) return make_pair(0.5,0.5);
double s = sqrt(1.-sqr(pt/hardPt));
double xe = emitterX();
return make_pair(0.5*(1.+xe-(1.-xe)*s),0.5*(1.+xe+(1.-xe)*s));
}
double IFMassiveTildeKinematics::lastZ() const {
Energy2 scale = 2.*(realEmissionMomentum()*realEmitterMomentum()
-realEmissionMomentum()*realSpectatorMomentum()
+realEmitterMomentum()*realSpectatorMomentum());
double x = subtractionParameters()[0];
double u = subtractionParameters()[1];
double muk2 = sqr(bornSpectatorData()->hardProcessMass())/scale;
return u + x - u*x*(1.-muk2);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFMassiveTildeKinematics::persistentOutput(PersistentOStream &) const {
}
void IFMassiveTildeKinematics::persistentInput(PersistentIStream &, int) {
}
void IFMassiveTildeKinematics::Init() {
static ClassDocumentation<IFMassiveTildeKinematics> documentation
("IFMassiveTildeKinematics implements the 'tilde' kinematics for "
"a initial-final subtraction dipole involving a massive particle.");
}
// *** 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<IFMassiveTildeKinematics,TildeKinematics>
describeHerwigIFMassiveTildeKinematics("Herwig::IFMassiveTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/IFMassiveTildeKinematics.h
@@ -1,138 +1,123 @@
// -*- C++ -*-
//
// IFMassiveTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IFMassiveTildeKinematics_H
#define HERWIG_IFMassiveTildeKinematics_H
//
// This is the declaration of the IFMassiveTildeKinematics class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/TildeKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Martin Stoll
*
* \brief IFMassiveTildeKinematics implements the 'tilde' kinematics for
* a initial-final subtraction dipole.
*
*/
class IFMassiveTildeKinematics: public TildeKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- IFMassiveTildeKinematics();
-
- /**
- * The destructor.
- */
- virtual ~IFMassiveTildeKinematics();
- //@}
-
-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 pt associated to emitter emission and sppectator momentum.
*/
virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt ) const;
/**
* Return the momentum fraction associated to the last splitting.
*/
virtual double lastZ() 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.
*/
IFMassiveTildeKinematics & operator=(const IFMassiveTildeKinematics &) = delete;
};
}
#endif /* HERWIG_IFMassiveTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/IILightTildeKinematics.cc
@@ -1,125 +1,120 @@
// -*- C++ -*-
//
// IILightTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 IILightTildeKinematics class.
//
#include "IILightTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-IILightTildeKinematics::IILightTildeKinematics() {}
-
-IILightTildeKinematics::~IILightTildeKinematics() {}
-
IBPtr IILightTildeKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IILightTildeKinematics::fullclone() const {
return new_ptr(*this);
}
Lorentz5Momentum IILightTildeKinematics::transform(const Lorentz5Momentum& k) const {
LorentzMomentum res =
k - 2.*((k*(K+Ktilde)/(K+Ktilde).m2())*(K+Ktilde)-((k*K)/(K.m2()))*Ktilde);
return res;
}
bool IILightTildeKinematics::doMap() {
Lorentz5Momentum emitter = realEmitterMomentum();
Lorentz5Momentum emission = realEmissionMomentum();
Lorentz5Momentum spectator = realSpectatorMomentum();
double x = (emitter*spectator - emitter*emission - spectator*emission)/(emitter*spectator);
double v = (emitter*emission)/(emitter*spectator);
subtractionParameters().resize(2);
subtractionParameters()[0] = x;
subtractionParameters()[1] = v;
bornEmitterMomentum() = x * emitter;
bornSpectatorMomentum() = spectator;
bornEmitterMomentum().setMass(ZERO);
bornEmitterMomentum().rescaleEnergy();
bornSpectatorMomentum().setMass(ZERO);
bornSpectatorMomentum().rescaleEnergy();
K = emitter + spectator - emission;
Ktilde = x * emitter + spectator;
return true;
}
Energy IILightTildeKinematics::lastPt() const {
Energy scale = sqrt(2.*(bornEmitterMomentum()*bornSpectatorMomentum()));
double x = subtractionParameters()[0];
double v = subtractionParameters()[1];
return scale * sqrt(v*(1.-x-v)/x);
}
Energy IILightTildeKinematics::lastPt(Lorentz5Momentum ,Lorentz5Momentum emission,Lorentz5Momentum )const {
return emission.perp();
}
pair<double,double> IILightTildeKinematics::zBounds(Energy pt, Energy hardPt) const {
if(pt>hardPt) return make_pair(0.5,0.5);
double root = (1.-emitterX())*sqrt(1.-sqr(pt/hardPt));
return make_pair(0.5*( 1.+emitterX() - root),0.5*( 1.+emitterX() + root));
}
double IILightTildeKinematics::lastZ() const {
double x = subtractionParameters()[0];
double v = subtractionParameters()[1];
return x + v;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IILightTildeKinematics::persistentOutput(PersistentOStream & os) const {
os << ounit(K,GeV) << ounit(Ktilde,GeV);
}
void IILightTildeKinematics::persistentInput(PersistentIStream & is, int) {
is >> iunit(K,GeV) >> iunit(Ktilde,GeV);
}
void IILightTildeKinematics::Init() {
static ClassDocumentation<IILightTildeKinematics> documentation
("IILightTildeKinematics implements the 'tilde' kinematics for "
"a initial-initial subtraction dipole.");
}
// *** 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<IILightTildeKinematics,TildeKinematics>
describeHerwigIILightTildeKinematics("Herwig::IILightTildeKinematics", "Herwig.so");
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,171 +1,156 @@
// -*- C++ -*-
//
// IILightTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 pt associated to emitter emission and sppectator momentum.
*/
//TODO: make this static?
virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const ;
/**
* Given a pt, return the boundaries on z
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt ) 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 &) = delete;
};
}
#endif /* HERWIG_IILightTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.cc
@@ -1,214 +1,210 @@
// -*- C++ -*-
//
// InvertedTildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the InvertedTildeKinematics class.
//
#include <limits>
#include "InvertedTildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Utilities/Rebinder.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
-
#include "Herwig/MatrixElement/Matchbox/Phasespace/RandomHelpers.h"
using namespace Herwig;
InvertedTildeKinematics::InvertedTildeKinematics()
: HandlerBase(), theJacobian(0.0), thePtCut(0.0*GeV) {}
-InvertedTildeKinematics::~InvertedTildeKinematics() {}
-
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
Lorentz5Momentum InvertedTildeKinematics::getKt(const Lorentz5Momentum& p1,
const Lorentz5Momentum& p2,
Energy pt,
double phi,
bool spacelike) const {
Lorentz5Momentum P;
if ( !spacelike )
P = p1 + p2;
else
P = p1 - p2;
Energy2 Q2 = abs(P.m2());
Lorentz5Momentum Q =
!spacelike ?
Lorentz5Momentum(ZERO,ZERO,ZERO,sqrt(Q2),sqrt(Q2)) :
Lorentz5Momentum(ZERO,ZERO,sqrt(Q2),ZERO,-sqrt(Q2));
if ( spacelike && Q.z() < P.z() )
Q.setZ(-Q.z());
bool boost =
abs((P-Q).vect().mag2()/GeV2) > 1e-10 ||
abs((P-Q).t()/GeV) > 1e-5;
boost &= (P*Q-Q.mass2())/GeV2 > 1e-8;
Lorentz5Momentum inFrame1;
if ( boost )
inFrame1 = p1 + ((P*p1-Q*p1)/(P*Q-Q.mass2()))*(P-Q);
else
inFrame1 = p1;
Energy ptx = inFrame1.x();
Energy pty = inFrame1.y();
Energy q = 2.*inFrame1.z();
Energy Qp = sqrt(4.*(sqr(ptx)+sqr(pty))+sqr(q));
Energy Qy = sqrt(4.*sqr(pty)+sqr(q));
double cPhi = cos(phi);
double sPhi = sqrt(1.-sqr(cPhi));
if ( phi > Constants::pi )
sPhi = -sPhi;
Lorentz5Momentum kt;
if ( !spacelike ) {
kt.setT(ZERO);
kt.setX(pt*Qy*cPhi/Qp);
kt.setY(-pt*(4*ptx*pty*cPhi/Qp+q*sPhi)/Qy);
kt.setZ(2.*pt*(-ptx*q*cPhi/Qp + pty*sPhi)/Qy);
} else {
kt.setT(2.*pt*(ptx*q*cPhi+pty*Qp*sPhi)/(q*Qy));
kt.setX(pt*(Qp*q*cPhi+4.*ptx*pty*sPhi)/(q*Qy));
kt.setY(pt*Qy*sPhi/q);
kt.setZ(ZERO);
}
if ( boost )
kt = kt + ((P*kt-Q*kt)/(P*Q-Q.mass2()))*(P-Q);
kt.setMass(-pt);
kt.rescaleRho();
return kt;
}
Energy InvertedTildeKinematics::lastScale() const {
if ( ( theDipole->bornEmitter() < 2 && theDipole->bornSpectator() > 1 ) ||
( theDipole->bornEmitter() > 1 && theDipole->bornSpectator() < 2 ) ) {
return -(bornEmitterMomentum()-bornSpectatorMomentum()).m();
}
return (bornEmitterMomentum()+bornSpectatorMomentum()).m();
}
pair<Energy,double> InvertedTildeKinematics::generatePtZ(double& jac, const double * r,
double pow, vector<double>* ) const {
double kappaMin =
ptCut() != ZERO ?
sqr(ptCut()/ptMax()) :
sqr(0.1*GeV/GeV);
double kappa;
using namespace RandomHelpers;
if ( ptCut() > ZERO ) {
pair<double,double> kw = pow==1. ?
generate(inverse(0.,kappaMin,1.),r[0]) :
generate(power(0.,-pow,kappaMin,1.),r[0]);
kappa = kw.first;
jac *= kw.second;
} else {
pair<double,double> kw =
generate((piecewise(),
flat(1e-4,kappaMin),
match(inverse(0.,kappaMin,1.))),r[0]);
kappa = kw.first;
jac *= kw.second;
}
Energy pt = sqrt(kappa)*ptMax();
pair<double,double> zLims = zBounds(pt);
pair<double,double> zw(0,0);// =
// generate(inverse(0.,zLims.first,zLims.second)+
// inverse(1.,zLims.first,zLims.second),r[1]);
// FlatZ = 1
if ( theDipole->samplingZ() == 1 ) {
zw = generate(flat(zLims.first,zLims.second),r[1]);
}
// OneOverZ = 2
if ( theDipole->samplingZ() == 2 ) {
zw = generate(inverse(0.0,zLims.first,zLims.second),r[1]);
}
// OneOverOneMinusZ = 3
if ( theDipole->samplingZ() == 3 ) {
zw = generate(inverse(1.0,zLims.first,zLims.second),r[1]);
}
// OneOverZOneMinusZ = 4
if ( theDipole->samplingZ() == 4 ) {
zw = generate(inverse(0.0,zLims.first,zLims.second) +
inverse(1.0,zLims.first,zLims.second),r[1]);
}
double z = zw.first;
jac *= zw.second;
jac *= sqr(ptMax()/lastScale());
return make_pair(pt,z);
}
void InvertedTildeKinematics::rebind(const TranslationMap & trans) {
theDipole = trans.translate(theDipole);
HandlerBase::rebind(trans);
}
IVector InvertedTildeKinematics::getReferences() {
IVector ret = HandlerBase::getReferences();
ret.push_back(theDipole);
return ret;
}
void InvertedTildeKinematics::persistentOutput(PersistentOStream & os) const {
os << theDipole << theRealXComb << theBornXComb
<< ounit(theRealEmitterMomentum,GeV) << ounit(theRealEmissionMomentum,GeV)
<< ounit(theRealSpectatorMomentum,GeV) << theJacobian
<< ounit(thePtCut,GeV);
}
void InvertedTildeKinematics::persistentInput(PersistentIStream & is, int) {
is >> theDipole >> theRealXComb >> theBornXComb
>> iunit(theRealEmitterMomentum,GeV) >> iunit(theRealEmissionMomentum,GeV)
>> iunit(theRealSpectatorMomentum,GeV) >> theJacobian
>> iunit(thePtCut,GeV);
}
void InvertedTildeKinematics::Init() {
static ClassDocumentation<InvertedTildeKinematics> documentation
("InvertedTildeKinematics is the base class for the inverted 'tilde' "
"kinematics being used for subtraction terms in the "
"formalism of Catani and Seymour.");
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeAbstractClass<InvertedTildeKinematics,HandlerBase>
describeInvertedTildeKinematics("Herwig::InvertedTildeKinematics", "Herwig.so");
diff --git a/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h b/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h
--- a/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h
+++ b/MatrixElement/Matchbox/Phasespace/InvertedTildeKinematics.h
@@ -1,450 +1,442 @@
// -*- C++ -*-
//
// InvertedTildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_InvertedTildeKinematics_H
#define HERWIG_InvertedTildeKinematics_H
//
// This is the declaration of the InvertedTildeKinematics class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief InvertedTildeKinematics is the base class for the inverted 'tilde'
* kinematics being used for subtraction terms in the
* formalism of Catani and Seymour.
*
*/
class InvertedTildeKinematics: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
InvertedTildeKinematics();
- /**
- * The destructor.
- */
- virtual ~InvertedTildeKinematics();
- //@}
-
public:
/** @name Access to kinematic quantities. */
//@{
/**
* Return the momentum of the emitter in the real emission process
*/
const Lorentz5Momentum& realEmitterMomentum() const { return theRealEmitterMomentum; }
/**
* Return the momentum of the emission in the real emission process
*/
const Lorentz5Momentum& realEmissionMomentum() const { return theRealEmissionMomentum; }
/**
* Return the momentum of the spectator in the real emission process
*/
const Lorentz5Momentum& realSpectatorMomentum() const { return theRealSpectatorMomentum; }
/**
* Return the momentum of the emitter in the underlying Born process
*/
const Lorentz5Momentum& bornEmitterMomentum() const {
return theBornXComb->meMomenta()[theDipole->bornEmitter()];
}
/**
* Return the momentum of the spectator in the underlying Born process
*/
const Lorentz5Momentum& bornSpectatorMomentum() const {
return theBornXComb->meMomenta()[theDipole->bornSpectator()];
}
/**
* Return the momentum fraction of the emitter
*/
double emitterX() const {
return
theDipole->bornEmitter() == 0 ?
theBornXComb->lastX1() :
theBornXComb->lastX2();
}
/**
* Return the momentum fraction of the spectator
*/
double spectatorX() const {
return
theDipole->bornSpectator() == 0 ?
theBornXComb->lastX1() :
theBornXComb->lastX2();
}
/**
* Return the vector of dimensionless variables calculated
*/
const vector<double>& subtractionParameters() const { return theDipole->subtractionParameters(); }
/**
* Return true, if this InvertedTildeKinematics object needs to transform
* all other particles in the process except the emitter, emission and spectator
*/
virtual bool doesTransform() const { return false; }
/**
* If this InvertedTildeKinematics object needs to transform all other particles
* in the process except the emitter, emission and spectator, return the transformed
* momentum.
*/
virtual Lorentz5Momentum transform(const Lorentz5Momentum& p) const { return p; }
/**
* Return the centre of mass energy for the underlying Born configuration
*/
Energy2 sHat() const { return theBornXComb->lastSHat(); }
//@}
public:
/**
* Clone this object
*/
Ptr<InvertedTildeKinematics>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<InvertedTildeKinematics>::ptr>(clone());
}
/** @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;
}
/**
* Return the real xcomb
*/
tcStdXCombPtr realXComb() const { return theRealXComb; }
/**
* Return the Born xcomb
*/
tcStdXCombPtr bornXComb() const { return theBornXComb; }
/**
* 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; }
/**
* Return the number of random numbers needed to generate
* a real emission configuration off the underlying Born
* configuration.
*/
virtual int nDimRadiation() const { return 3; }
/**
* Perform the mapping of the tilde kinematics for the
* last selected process and store all dimensionless
* variables in the subtractionParameters() vector.
* Return false, if the calculation of the real
* kinematics was impossible for the selected configuration
* and true on success.
*/
virtual bool doMap(const double *) = 0;
/**
* Set an optional cutoff on the emission's
* transverse momentum.
*/
void ptCut(Energy pt) { thePtCut = pt; }
/**
* Return the optional cutoff on the emission's
* transverse momentum.
*/
Energy ptCut() const { return thePtCut; }
/**
* Return the random number index
* corresponding to the evolution variable.
*/
virtual int evolutionVariable() const { return 0; }
/**
* Return the cutoff on the evolution
* random number corresponding to the pt cut.
*/
virtual double evolutionCutoff() const { return 0.0; }
/**
* Return the pt associated to the last generated 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;
/**
* Return the upper bound on pt
*/
virtual Energy ptMax() const = 0;
/**
* Given a pt and a hard pt, return the boundaries on z; if the hard
* pt is zero, ptMax() will be used.
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt = ZERO) const = 0;
/**
* Generate pt and z
*/
virtual pair<Energy,double> generatePtZ(double& jac, const double * r,
double power=1., vector<double>* values = NULL) const;
/**
* Return the single particle phase space weight in units
* of sHat() for the last selected configuration.
*/
double jacobian() const { return theJacobian; }
/**
* 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 real emission process
*/
Lorentz5Momentum& realEmitterMomentum() { return theRealEmitterMomentum; }
/**
* Access the momentum of the emission in the real emission process
*/
Lorentz5Momentum& realEmissionMomentum() { return theRealEmissionMomentum; }
/**
* Access the momentum of the spectator in the real emission process
*/
Lorentz5Momentum& realSpectatorMomentum() { return theRealSpectatorMomentum; }
/**
* Access the vector of dimensionless variables calculated
*/
vector<double>& subtractionParameters() { return theDipole->subtractionParameters(); }
/**
* Set the single particle phase space weight in units
* of sHat() for the last selected configuration.
*/
void jacobian(double w) { theJacobian = w; }
/**
* Calculate a transverse momentum for the given momenta,
* invariant pt and azimuth.
*/
Lorentz5Momentum getKt(const Lorentz5Momentum& p1,
const Lorentz5Momentum& p2,
Energy pt,
double phi,
bool spacelike = false) 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();
// 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 InvertedTildeKinematics 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 real emission process
*/
Lorentz5Momentum theRealEmitterMomentum;
/**
* The momentum of the emission in the real emission process
*/
Lorentz5Momentum theRealEmissionMomentum;
/**
* The momentum of the spectator in the real emission process
*/
Lorentz5Momentum theRealSpectatorMomentum;
/**
* Return the single particle phase space weight in units
* of sHat() for the last selected configuration.
*/
double theJacobian;
/**
* The optional cutoff on the emission's
* transverse momentum.
*/
Energy thePtCut;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
InvertedTildeKinematics & operator=(const InvertedTildeKinematics &) = delete;
};
}
#endif /* HERWIG_InvertedTildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.cc b/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.cc
--- a/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.cc
+++ b/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.cc
@@ -1,565 +1,563 @@
// -*- C++ -*-
//
// MatchboxPhasespace.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxPhasespace class.
//
#include "MatchboxPhasespace.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig/MatrixElement/Matchbox/Utility/ProcessData.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
using namespace Herwig;
MatchboxPhasespace::MatchboxPhasespace()
: singularCutoff(10*GeV), theUseMassGenerators(false),
theLoopParticleIdMin(200001), theLoopParticleIdMax(200100) {}
-MatchboxPhasespace::~MatchboxPhasespace() {}
-
void MatchboxPhasespace::cloneDependencies(const std::string&) {}
Ptr<MatchboxFactory>::tcptr MatchboxPhasespace::factory() const {
return MatchboxFactory::currentFactory();
}
Ptr<ProcessData>::tptr MatchboxPhasespace::processData() const {
return factory()->processData();
}
double MatchboxPhasespace::generateKinematics(const double* r,
vector<Lorentz5Momentum>& momenta) {
diagramWeights().clear();
cPDVector::const_iterator pd = mePartonData().begin() + 2;
vector<Lorentz5Momentum>::iterator p = momenta.begin() + 2;
double massJacobian = 1.;
Energy summ = ZERO;
if ( useMassGenerators() ) {
Energy gmass = ZERO;
tGenericMassGeneratorPtr mgen;
Energy maxMass =
(!haveX1X2() && momenta.size() > 3) ?
sqrt(lastSHat()) : sqrt(lastS());
for ( ; pd != mePartonData().end(); ++pd, ++p ) {
mgen = processData()->massGenerator(*pd);
if ( mgen && !isInvertible() ) {
Energy massMax = min((**pd).massMax(),maxMass);
Energy massMin = (**pd).massMin();
if ( massMin > massMax )
return 0.0;
gmass = mgen->mass(massJacobian,**pd,massMin,massMax,r[0]);
++r;
} else if ( (**pd).hardProcessWidth() != ZERO ) {
Energy massMax = min((**pd).massMax(),maxMass);
Energy massMin = (**pd).massMin();
if ( massMin > massMax )
return 0.0;
// use a standard Breit Wigner here which we can invert
// see invertKinematics as well
double bwILow =
atan((sqr(massMin)-sqr((**pd).hardProcessMass()))/((**pd).hardProcessMass() * (**pd).hardProcessWidth()));
double bwIUp =
atan((sqr(massMax)-sqr((**pd).hardProcessMass()))/((**pd).hardProcessMass() * (**pd).hardProcessWidth()));
gmass = sqrt(sqr((**pd).hardProcessMass()) +
(**pd).hardProcessMass()*(**pd).hardProcessWidth()*tan(bwILow+r[0]*(bwIUp-bwILow)));
++r;
} else {
gmass = (**pd).hardProcessMass();
}
maxMass -= gmass;
p->setMass(gmass);
summ += gmass;
}
} else {
for ( ; pd != mePartonData().end(); ++pd, ++p ) {
summ += (**pd).hardProcessMass();
p->setMass((**pd).hardProcessMass());
}
}
if ( momenta.size() > 3 && !haveX1X2() ) {
if ( summ > (momenta[0]+momenta[1]).m() )
return 0.0;
}
double weight = momenta.size() > 3 ?
generateTwoToNKinematics(r,momenta) :
generateTwoToOneKinematics(r,momenta);
fillDiagramWeights();
return weight*massJacobian;
}
double MatchboxPhasespace::generateTwoToOneKinematics(const double* r,
vector<Lorentz5Momentum>& momenta) {
double tau = momenta[2].mass2()/lastXCombPtr()->lastS();
double ltau = log(tau)/2.;
//old: y = ltau - 2.*r[0]*ltau; x1 = sqrt(tau)*exp(y); x2 = sqrt(tau)*exp(-y);
double x1=pow(tau,1.-r[0]);
double x2=pow(tau,r[0]);
// Due to the proton mass and P1.e() + P2.e() == lastS() we multiply here
// with the correction factor abs(P1.e()/P1.z()) to produce incoming
// p1/2 = (e1/2,0,0,+/- e1/2)
Lorentz5Momentum P1 = lastXCombPtr()->lastParticles().first->momentum();
ThreeVector<Energy> p1 = x1 * (P1.vect()) * abs(P1.e()/P1.z());
Lorentz5Momentum P2 = lastXCombPtr()->lastParticles().second->momentum();
ThreeVector<Energy> p2 = x2 * (P2.vect()) * abs(P2.e()/P2.z());
ThreeVector<Energy> q = p1 + p2;
momenta[0] = Lorentz5Momentum(momenta[0].mass(),p1);
momenta[1] = Lorentz5Momentum(momenta[1].mass(),p2);
momenta[2] = Lorentz5Momentum(momenta[2].mass(),q);
// check for energy conservation:
if ((momenta[0]+momenta[1]-momenta[2]).e()>pow(10,-9)*GeV)
generator()->log()
<< "Warning: Momentum conservation in generateTwoToOneKinematics not precise.\n"
<< flush;
lastXCombPtr()->lastX1X2({x1,x2});
lastXCombPtr()->lastSHat((momenta[0]+momenta[1]).m2());
return -4.*Constants::pi*ltau;
}
double MatchboxPhasespace::invertKinematics(const vector<Lorentz5Momentum>& momenta,
double* r) const {
if ( useMassGenerators() ) {
Energy gmass = ZERO;
Energy maxMass =
(!haveX1X2() && momenta.size() > 3) ?
sqrt((momenta[0]+momenta[1]).m2()) : sqrt(lastS());
cPDVector::const_iterator pd = mePartonData().begin() + 2;
vector<Lorentz5Momentum>::const_iterator p = momenta.begin() + 2;
for ( ; pd != mePartonData().end(); ++pd, ++p ) {
if ( (**pd).hardProcessWidth() != ZERO ) {
Energy massMax = min((**pd).massMax(),maxMass);
Energy massMin = (**pd).massMin();
if ( massMin > massMax )
return 0.0;
double bwILow =
atan((sqr(massMin)-sqr((**pd).hardProcessMass()))/((**pd).hardProcessMass() * (**pd).hardProcessWidth()));
double bwIUp =
atan((sqr(massMax)-sqr((**pd).hardProcessMass()))/((**pd).hardProcessMass() * (**pd).hardProcessWidth()));
gmass = p->mass();
double bw =
atan((sqr(gmass)-sqr((**pd).hardProcessMass()))/((**pd).hardProcessMass() * (**pd).hardProcessWidth()));
r[0] = (bw-bwILow)/(bwIUp-bwILow);
++r;
} else {
gmass = (**pd).hardProcessMass();
}
maxMass -= gmass;
}
}
return momenta.size() > 3 ?
invertTwoToNKinematics(momenta,r) :
invertTwoToOneKinematics(momenta,r);
}
double MatchboxPhasespace::invertTwoToOneKinematics(const vector<Lorentz5Momentum>& momenta,
double* r) const {
double tau = momenta[2].mass2()/lastXCombPtr()->lastS();
double ltau = log(tau)/2.;
r[0] = (ltau - (momenta[0]+momenta[1]).rapidity())/(2.*ltau);
return -4.*Constants::pi*ltau;
}
void MatchboxPhasespace::setCoupling(long a, long b, long c,
double coupling, bool includeCrossings) {
cPDPtr A = getParticleData(a);
cPDPtr B = getParticleData(b);
cPDPtr C = getParticleData(c);
if ( !A || !B || !C ) {
generator()->log() << "Warning: could not determine particle data for ids "
<< a << " " << b << " " << c << " when setting coupling in MatchboxPhasespace.\n"
<< flush;
return;
}
if ( !includeCrossings ) {
theCouplings->couplings()[LTriple(a,b,c)] = coupling;
return;
}
if ( A->CC() ) {
theCouplings->couplings()[LTriple(-a,b,c)] = coupling;
theCouplings->couplings()[LTriple(-a,c,b)] = coupling;
} else {
theCouplings->couplings()[LTriple(a,b,c)] = coupling;
theCouplings->couplings()[LTriple(a,c,b)] = coupling;
}
if ( B->CC() ) {
theCouplings->couplings()[LTriple(-b,a,c)] = coupling;
theCouplings->couplings()[LTriple(-b,c,a)] = coupling;
} else {
theCouplings->couplings()[LTriple(b,a,c)] = coupling;
theCouplings->couplings()[LTriple(b,c,a)] = coupling;
}
if ( C->CC() ) {
theCouplings->couplings()[LTriple(-c,a,b)] = coupling;
theCouplings->couplings()[LTriple(-c,b,a)] = coupling;
} else {
theCouplings->couplings()[LTriple(c,a,b)] = coupling;
theCouplings->couplings()[LTriple(c,b,a)] = coupling;
}
}
string MatchboxPhasespace::doSetCoupling(string in) {
istringstream is(in);
long a,b,c; double coupling;
is >> a >> b >> c >> coupling;
if ( !is )
return "MatchboxPhasespace: error in setting coupling.";
setCoupling(a,b,c,coupling,true);
return "";
}
string MatchboxPhasespace::doSetPhysicalCoupling(string in) {
istringstream is(in);
long a,b,c; double coupling;
is >> a >> b >> c >> coupling;
if ( !is )
return "MatchboxPhasespace: error in setting coupling.";
setCoupling(a,b,c,coupling,false);
return "";
}
pair<double,Lorentz5Momentum>
MatchboxPhasespace::timeLikeWeight(const Tree2toNDiagram& diag,
int branch, double flatCut) const {
pair<int,int> children = diag.children(branch);
if ( children.first == -1 ) {
return make_pair(1.,meMomenta()[diag.externalId(branch)]);
}
pair<double,Lorentz5Momentum> res
= timeLikeWeight(diag,children.first,flatCut);
pair<double,Lorentz5Momentum> other
= timeLikeWeight(diag,children.second,flatCut);
res.first *= other.first;
res.second += other.second;
LTriple vertexKey(diag.allPartons()[branch]->id(),
diag.allPartons()[children.first]->id(),
diag.allPartons()[children.second]->id());
map<LTriple,double>::const_iterator cit = theCouplings->couplings().find(vertexKey);
if ( cit != theCouplings->couplings().end() ){
res.first *= cit->second;
}
Energy2 mass2 = sqr(diag.allPartons()[branch]->hardProcessMass());
Energy2 width2 = sqr(diag.allPartons()[branch]->hardProcessWidth());
if ( abs(diag.allPartons()[branch]->id()) >= theLoopParticleIdMin
&& abs(diag.allPartons()[branch]->id()) <= theLoopParticleIdMax ) { // "loop particle"
if ( abs((res.second.m2()-mass2)/lastSHat()) > flatCut ) {
res.first /=
abs((res.second.m2()-mass2)/GeV2);
res.first *=
log(abs((res.second.m2()-mass2)/GeV2)); // normal. of the argument in the log?
}
} else {
if ( width2 == ZERO ) {
if ( abs((res.second.m2()-mass2)/lastSHat()) > flatCut )
res.first /=
abs((res.second.m2()-mass2)/GeV2);
} else {
res.first /=
(sqr((res.second.m2()-mass2)/GeV2) +
mass2*width2/sqr(GeV2))/(abs(res.second.m2()/GeV2));
}
}
return res;
}
double MatchboxPhasespace::spaceLikeWeight(const Tree2toNDiagram& diag,
const Lorentz5Momentum& incoming,
int branch, double flatCut) const {
if ( branch == -1 )
return 1.;
pair<int,int> children = diag.children(branch);
pair<double,Lorentz5Momentum> res =
timeLikeWeight(diag,children.second,flatCut);
LTriple vertexKey(diag.allPartons()[branch]->id(),
diag.allPartons()[children.first]->id(),
diag.allPartons()[children.second]->id());
if ( children.first == diag.nSpace() - 1 ) {
if ( diag.allPartons()[children.first]->CC() )
vertexKey = LTriple(diag.allPartons()[branch]->id(),
diag.allPartons()[children.second]->id(),
diag.allPartons()[children.first]->CC()->id());
else
vertexKey = LTriple(diag.allPartons()[branch]->id(),
diag.allPartons()[children.second]->id(),
diag.allPartons()[children.first]->id());
}
map<LTriple,double>::const_iterator cit = theCouplings->couplings().find(vertexKey);
if ( cit != theCouplings->couplings().end() ){
res.first *= cit->second;
}
if ( children.first == diag.nSpace() - 1 ) {
return res.first;
}
res.second = incoming - res.second;
Energy2 mass2 = sqr(diag.allPartons()[children.first]->hardProcessMass());
Energy2 width2 = sqr(diag.allPartons()[children.first]->hardProcessWidth());
if ( abs(diag.allPartons()[children.first]->id()) >= theLoopParticleIdMin
&& (diag.allPartons()[children.first]->id()) <= theLoopParticleIdMax ) { // "loop particle"
if ( abs((res.second.m2()-mass2)/lastSHat()) > flatCut ) {
res.first /=
abs((res.second.m2()-mass2)/GeV2);
res.first *=
log(abs((res.second.m2()-mass2)/GeV2)); // normal. of the argument in the log?
}
} else {
if ( width2 == ZERO ) {
if ( abs((res.second.m2()-mass2)/lastSHat()) > flatCut )
res.first /=
abs((res.second.m2()-mass2)/GeV2);
} else {
res.first /=
(sqr((res.second.m2()-mass2)/GeV2) +
mass2*width2/sqr(GeV2))/(abs(res.second.m2()/GeV2));
}
}
return
res.first * spaceLikeWeight(diag,res.second,children.first,flatCut);
}
void MatchboxPhasespace::fillDiagramWeights(double flatCut) {
if ( !diagramWeights().empty() )
return;
for ( auto & d : lastXComb().diagrams() ) {
diagramWeights()[d->id()] =
spaceLikeWeight(dynamic_cast<const Tree2toNDiagram&>(*d),meMomenta()[0],0,flatCut);
}
}
Selector<MEBase::DiagramIndex>
MatchboxPhasespace::selectDiagrams(const MEBase::DiagramVector& diags) const {
Selector<MEBase::DiagramIndex> ret;
for ( MEBase::DiagramIndex d = 0; d < diags.size(); ++d ) {
ret.insert(diagramWeight(dynamic_cast<const Tree2toNDiagram&>(*diags[d])),d);
}
return ret;
}
bool MatchboxPhasespace::matchConstraints(const vector<Lorentz5Momentum>& momenta) {
if ( singularLimits().empty() )
return true;
lastSingularLimit() = singularLimits().begin();
for ( ; lastSingularLimit() != singularLimits().end(); ++lastSingularLimit() ) {
if ( lastSingularLimit()->first == lastSingularLimit()->second &&
momenta[lastSingularLimit()->first].t() < singularCutoff )
break;
if ( lastSingularLimit()->first != lastSingularLimit()->second &&
sqrt(momenta[lastSingularLimit()->first]*
momenta[lastSingularLimit()->second]) < singularCutoff ) {
bool match = true;
for ( set<pair<size_t,size_t> >::const_iterator other =
singularLimits().begin(); other != singularLimits().end(); ++other ) {
if ( other == lastSingularLimit() )
continue;
if ( other->first == other->second &&
momenta[other->first].t() < singularCutoff ) {
match = false;
break;
}
if ( other->first != other->second &&
sqrt(momenta[other->first]*
momenta[other->second]) < singularCutoff ) {
match = false;
break;
}
}
if ( match )
break;
}
}
return lastSingularLimit() != singularLimits().end();
}
int MatchboxPhasespace::nDim(const cPDVector& data) const {
int ndimps = nDimPhasespace(data.size()-2);
if ( useMassGenerators() ) {
for ( cPDVector::const_iterator pd = data.begin();
pd != data.end(); ++pd ) {
if ( (**pd).massGenerator() ||
(**pd).hardProcessWidth() != ZERO ) {
++ndimps;
}
}
}
return ndimps;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxPhasespace::persistentOutput(PersistentOStream & os) const {
os << theLastXComb
<< ounit(singularCutoff,GeV) << theUseMassGenerators
<< theLoopParticleIdMin << theLoopParticleIdMax
<< theCouplings;
}
void MatchboxPhasespace::persistentInput(PersistentIStream & is, int) {
is >> theLastXComb
>> iunit(singularCutoff,GeV) >> theUseMassGenerators
>> theLoopParticleIdMin >> theLoopParticleIdMax
>> theCouplings;
lastMatchboxXComb(theLastXComb);
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeAbstractClass<MatchboxPhasespace,HandlerBase>
describeMatchboxPhasespace("Herwig::MatchboxPhasespace", "Herwig.so");
void MatchboxPhasespace::Init() {
static ClassDocumentation<MatchboxPhasespace> documentation
("MatchboxPhasespace defines an abstract interface to a phase "
"space generator.");
static Parameter<MatchboxPhasespace,Energy> interfaceSingularCutoff
("SingularCutoff",
"[debug] Cutoff below which a region is considered singular.",
&MatchboxPhasespace::singularCutoff, GeV, 10.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
interfaceSingularCutoff.rank(-1);
/*
static Switch<MatchboxPhasespace,bool> interfaceUseMassGenerators
("UseMassGenerators",
"Use mass generators instead of fixed masses.",
&MatchboxPhasespace::theUseMassGenerators, false, false, false);
static SwitchOption interfaceUseMassGeneratorsYes
(interfaceUseMassGenerators,
"Yes",
"Use mass generators.",
true);
static SwitchOption interfaceUseMassGeneratorsNo
(interfaceUseMassGenerators,
"No",
"Do not use mass generators.",
false);
*/
static Command<MatchboxPhasespace> interfaceSetCoupling
("SetCoupling",
"",
&MatchboxPhasespace::doSetCoupling, false);
static Command<MatchboxPhasespace> interfaceSetPhysicalCoupling
("SetPhysicalCoupling",
"",
&MatchboxPhasespace::doSetPhysicalCoupling, false);
static Parameter<MatchboxPhasespace,int> interfaceLoopParticleIdMin
("LoopParticleIdMin",
"First id in a range of id's meant to denote fictitious "
"'ghost' particles to be used by the diagram generator "
"in loop induced processes.",
&MatchboxPhasespace::theLoopParticleIdMin, 200001, 0, 0,
false, false, Interface::lowerlim);
interfaceLoopParticleIdMin.rank(-1);
static Parameter<MatchboxPhasespace,int> interfaceLoopParticleIdMax
("LoopParticleIdMax",
"Last id in a range of id's meant to denote fictitious "
"'ghost' particles to be used by the diagram generator "
"in loop induced processes.",
&MatchboxPhasespace::theLoopParticleIdMax, 200100, 0, 0,
false, false, Interface::lowerlim);
interfaceLoopParticleIdMax.rank(-1);
static Reference<MatchboxPhasespace,PhasespaceCouplings> interfaceCouplingData
("CouplingData",
"Set the storage for the couplings.",
&MatchboxPhasespace::theCouplings, false, false, true, false, false);
interfaceCouplingData.rank(-1);
}
diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h b/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h
--- a/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h
+++ b/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h
@@ -1,366 +1,358 @@
// -*- C++ -*-
//
// MatchboxPhasespace.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MatchboxPhasespace_H
#define HERWIG_MatchboxPhasespace_H
//
// This is the declaration of the MatchboxPhasespace class.
//
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "Herwig/MatrixElement/Matchbox/Utility/LastMatchboxXCombInfo.h"
#include "Herwig/MatrixElement/Matchbox/Utility/ProcessData.fh"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.fh"
#include "Herwig/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief Wrap around a vector of random numbers to behave as a stream
* of those.
*/
struct StreamingRnd {
/**
* The random numbers
*/
const double* numbers;
/**
* The number of random numbers available.
*/
size_t nRnd;
/**
* Default constructor.
*/
StreamingRnd()
: numbers(0), nRnd(0) {}
/**
* Construct from random numbers.
*/
explicit StreamingRnd(const double* newNumbers,
size_t n)
: numbers(newNumbers), nRnd(n) {}
/**
* Return next random number
*/
inline double operator()() {
assert(numbers && nRnd > 0);
const double ret = numbers[0];
++numbers; --nRnd;
return ret;
}
};
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxPhasespace defines an abstract interface to a phase
* space generator.
*
*/
class MatchboxPhasespace:
public HandlerBase,
public LastXCombInfo<StandardXComb>,
public LastMatchboxXCombInfo {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxPhasespace();
- /**
- * The destructor.
- */
- virtual ~MatchboxPhasespace();
- //@}
-
public:
/**
* Set the XComb object steering the Born matrix
* element this class represents virtual corrections to.
*/
virtual void setXComb(tStdXCombPtr xc) {
theLastXComb = xc;
lastMatchboxXComb(xc);
}
/**
* Return the factory object
*/
Ptr<MatchboxFactory>::tcptr factory() const;
/**
* Return the process data object
*/
Ptr<ProcessData>::tptr processData() const;
/**
* Generate a phase space point and return its weight.
*/
virtual double generateKinematics(const double* r,
vector<Lorentz5Momentum>& momenta);
/**
* Generate a phase space point and return its weight.
*/
virtual double generateTwoToNKinematics(const double*,
vector<Lorentz5Momentum>& momenta) = 0;
/**
* Generate a 2 -> 1 phase space point and return its weight.
*/
virtual double generateTwoToOneKinematics(const double*,
vector<Lorentz5Momentum>& momenta);
/**
* Return the number of random numbers required to produce a given
* multiplicity final state.
*/
virtual int nDim(const cPDVector&) const;
/**
* Return the number of random numbers required to produce a given
* multiplicity final state.
*/
virtual int nDimPhasespace(int nFinal) const = 0;
/**
* Return true, if this phasespace generator will generate incoming
* partons itself.
*/
virtual bool haveX1X2() const { return false; }
/**
* Return true, if this phase space generator expects
* the incoming partons in their center-of-mass system
*/
virtual bool wantCMS() const { return true; }
/**
* True, if mass generators should be used instead of fixed masses
*/
bool useMassGenerators() const { return theUseMassGenerators; }
/**
* Fill a diagram selector for the last phase space point.
*/
virtual Selector<MEBase::DiagramIndex> selectDiagrams(const MEBase::DiagramVector&) const;
/**
* Return the momentum and weight appropriate to the given timelike
* branch of the diagram.
*/
pair<double,Lorentz5Momentum> timeLikeWeight(const Tree2toNDiagram& diag,
int branch, double flatCut) const;
/**
* Return the weight appropriate to the given spacelike branch of
* the diagram.
*/
double spaceLikeWeight(const Tree2toNDiagram& diag,
const Lorentz5Momentum& incoming,
int branch, double flatCut) const;
/**
* Return the weight appropriate to the given diagram.
*/
double diagramWeight(const Tree2toNDiagram& diag) const {
assert( !diagramWeights().empty() );
return diagramWeights().find(diag.id())->second;
}
/**
* Fill the diagram weights.
*/
void fillDiagramWeights(double flatCut = 0.0);
/**
* Clear the diagram weights.
*/
void clearDiagramWeights() {
diagramWeights().clear();
}
/**
* Clone this phase space generator.
*/
Ptr<MatchboxPhasespace>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<MatchboxPhasespace>::ptr>(clone());
}
/**
* Clone the dependencies, using a given prefix.
*/
virtual void cloneDependencies(const std::string& prefix = "");
public:
/**
* Return true, if this phase space generator is invertible
*/
virtual bool isInvertible() const { return false; }
/**
* Invert the given phase space point to the random numbers which
* would have generated it.
*/
virtual double invertKinematics(const vector<Lorentz5Momentum>& momenta,
double* r) const;
/**
* Invert the given phase space point to the random numbers which
* would have generated it.
*/
virtual double invertTwoToNKinematics(const vector<Lorentz5Momentum>&,
double*) const {
return 0.;
}
/**
* Invert the given 2 -> 1 phase space point to the random numbers which
* would have generated it.
*/
virtual double invertTwoToOneKinematics(const vector<Lorentz5Momentum>&, double*) const;
public:
/**
* Limit phasespace generation to a given collinear or soft limit.
*/
void singularLimit(size_t i, size_t j) {
if ( i > j )
swap(i,j);
singularLimits().insert(make_pair(i,j));
}
/**
* Return the last matched singular limit.
*/
const pair<size_t,size_t>& lastSingularIndices() const {
assert(lastSingularLimit() != singularLimits().end());
return *lastSingularLimit();
}
/**
* Return true, if constraints on phasespace generation have been met.
*/
bool matchConstraints(const vector<Lorentz5Momentum>& momenta);
protected:
/**
* Set a coupling for the given vertex; the convention is that all
* legs are outgoing, and all possible crossings will be taken care
* of. If not set, coupling weights default to one.
*/
void setCoupling(long a, long b, long c,
double coupling, bool includeCrossings = true);
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);
//@}
public:
/**
* 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).
private:
/**
* A cutoff below which a region is considered singular.
*/
Energy singularCutoff;
/**
* True, if mass generators should be used instead of fixed masses
*/
bool theUseMassGenerators;
/**
* Couplings to be used in diagram weighting
*/
Ptr<PhasespaceCouplings>::ptr theCouplings;
/**
* Interface function to setcoupling
*/
string doSetCoupling(string);
/**
* Interface function to setcoupling
*/
string doSetPhysicalCoupling(string);
/**
* The first id in a range of id's meant to denote fictitious
* 'ghost' particles to be used by the diagram generator
* in loop induced processes.
*/
int theLoopParticleIdMin;
/**
* The last id in a range of id's meant to denote fictitious
* 'ghost' particles to be used by the diagram generator
* in loop induced processes.
*/
int theLoopParticleIdMax;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxPhasespace & operator=(const MatchboxPhasespace &) = delete;
};
}
#endif /* HERWIG_MatchboxPhasespace_H */
diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxRambo.cc b/MatrixElement/Matchbox/Phasespace/MatchboxRambo.cc
--- a/MatrixElement/Matchbox/Phasespace/MatchboxRambo.cc
+++ b/MatrixElement/Matchbox/Phasespace/MatchboxRambo.cc
@@ -1,263 +1,261 @@
// -*- C++ -*-
//
// MatchboxRambo.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxRambo class.
//
#include "MatchboxRambo.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig/Utilities/GSLBisection.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxRambo::MatchboxRambo()
: needToReshuffle(false), theMakeReferenceSample(false),
referenceSample(0) {}
-MatchboxRambo::~MatchboxRambo() {}
-
IBPtr MatchboxRambo::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxRambo::fullclone() const {
return new_ptr(*this);
}
static double weights[7] = {
-1.,-1.,
0.039788735772973833942,
0.00012598255637968550463,
1.3296564302788840628E-7,
7.0167897579949011130E-11,
2.2217170114046130768E-14
};
void MatchboxRambo::setXComb(tStdXCombPtr xc) {
MatchboxPhasespace::setXComb(xc);
needToReshuffle = false;
if ( xc ) {
for ( cPDVector::const_iterator d = mePartonData().begin();
d != mePartonData().end(); ++d ) {
if ( (**d).hardProcessMass() != ZERO ) {
needToReshuffle = true;
break;
}
}
}
}
void MatchboxRambo::dumpReference(const vector<Lorentz5Momentum>& momenta, double weight) const {
*referenceSample << lastX1() << " " << lastX2() << " ";
Boost toLab = (lastPartons().first->momentum() +
lastPartons().second->momentum()).boostVector();
for ( vector<Lorentz5Momentum>::const_iterator p = momenta.begin();
p != momenta.end(); ++p ) {
Lorentz5Momentum pl = *p;
if ( toLab.mag2() > Constants::epsilon )
pl.boost(toLab);
*referenceSample
<< (pl.x()/GeV) << " "
<< (pl.y()/GeV) << " "
<< (pl.z()/GeV) << " "
<< (pl.t()/GeV) << " "
<< (pl.mass()/GeV) << " ";
}
double ymax = lastCuts().yHatMax();
double ymin = lastCuts().yHatMin();
double km = log(lastCuts().sHatMax()/lastCuts().sHatMin());
ymax = min(ymax, log(lastCuts().x1Max()*sqrt(lastS()/lastSHat())));
ymin = max(ymin, -log(lastCuts().x2Max()*sqrt(lastS()/lastSHat())));
*referenceSample << weight*km*(ymax-ymin)/(lastX1()*lastX2()) << "\n" << flush;
}
double MatchboxRambo::generateTwoToNKinematics(const double* r,
vector<Lorentz5Momentum>& momenta) {
if ( theMakeReferenceSample ) {
map<cPDVector,ofstream*>::iterator ref =
referenceSamples.find(mePartonData());
if ( ref == referenceSamples.end() ) {
ostringstream refname;
for ( cPDVector::const_iterator p = mePartonData().begin();
p != mePartonData().end(); ++p ) {
refname << (**p).PDGName();
}
refname << ".rambo";
referenceSamples[mePartonData()] = new ofstream(refname.str().c_str(),std::ios_base::app);
ref = referenceSamples.find(mePartonData());
*(ref->second) << setprecision(26);
}
assert(ref != referenceSamples.end());
referenceSample = ref->second;
}
size_t offset = 2;
if ( lastXCombPtr() )
offset = dynamic_cast<const Tree2toNDiagram&>(*lastXComb().diagrams().front()).nSpace() > 0 ? 2 : 1;
Energy w = sqrt(lastSHat());
size_t count = 0;
Lorentz5Momentum Q;
for ( vector<Lorentz5Momentum>::iterator k = momenta.begin() + offset;
k != momenta.end(); ++k ) {
Energy q = -w*log(r[count]*r[count+1]);
double ct = 2.*r[count+2]-1.;
double st = sqrt(1.-sqr(ct));
double phi = 2.*Constants::pi*r[count+3];
double cphi = cos(phi);
double sphi = sqrt(1.-sqr(cphi));
if ( phi > Constants::pi )
sphi = -sphi;
(*k).setMass(ZERO);
(*k).setT(q);
(*k).setX(q*cphi*st);
(*k).setY(q*sphi*st);
(*k).setZ(q*ct);
count += 4;
Q += *k;
}
Energy M = sqrt(Q.m2());
double x = w/M;
Boost beta = -(Q.vect() * (1./M));
double gamma = Q.t()/M;
double a = 1./(1.+gamma);
for ( vector<Lorentz5Momentum>::iterator k = momenta.begin() + offset;
k != momenta.end(); ++k ) {
Energy q = (*k).t();
Energy bq = beta*(*k).vect();
(*k).setT(x*(gamma*q+bq));
(*k).setVect(x*((*k).vect()+(q+a*bq)*beta));
}
size_t n = momenta.size()-offset;
double weight = weights[n];
if ( !needToReshuffle ) {
if ( !matchConstraints(momenta) )
return 0.;
if ( theMakeReferenceSample )
dumpReference(momenta, weight);
return weight;
}
double xi;
ReshuffleEquation solve(w,mePartonData().begin()+offset,mePartonData().end(),
momenta.begin()+2,momenta.end());
GSLBisection solver(1e-10,1e-8,10000);
try {
xi = solver.value(solve,0.0,1.1);
} catch (GSLBisection::GSLerror) {
return 0.;
} catch (GSLBisection::IntervalError) {
return 0.;
}
weight *= pow(xi,3.*(n-1.));
Energy num = ZERO;
Energy den = ZERO;
cPDVector::const_iterator d = mePartonData().begin()+offset;
for ( vector<Lorentz5Momentum>::iterator k = momenta.begin()+offset;
k != momenta.end(); ++k, ++d ) {
num += (*k).vect().mag2()/(*k).t();
Energy q = (*k).t();
(*k).setT(sqrt(sqr((**d).hardProcessMass())+xi*xi*sqr((*k).t())));
(*k).setVect(xi*(*k).vect());
weight *= q/(*k).t();
den += (*k).vect().mag2()/(*k).t();
(*k).setMass((**d).hardProcessMass());
}
if ( !matchConstraints(momenta) )
return 0.;
weight *= num/den;
if ( theMakeReferenceSample )
dumpReference(momenta, weight);
return weight;
}
Energy MatchboxRambo::ReshuffleEquation::operator() (double xi) const {
cPDVector::const_iterator d = dataBegin;
vector<Lorentz5Momentum>::const_iterator p = momentaBegin;
Energy res = -w;
for ( ; d != dataEnd; ++d, ++p ) {
res += sqrt(sqr((**d).hardProcessMass()) +
xi*xi*sqr(p->t()));
}
return res;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxRambo::persistentOutput(PersistentOStream & os) const {
os << needToReshuffle << theMakeReferenceSample;
}
void MatchboxRambo::persistentInput(PersistentIStream & is, int) {
is >> needToReshuffle >> theMakeReferenceSample;
}
// *** 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<MatchboxRambo,MatchboxPhasespace>
describeHerwigMatchboxRambo("Herwig::MatchboxRambo", "Herwig.so");
void MatchboxRambo::Init() {
static ClassDocumentation<MatchboxRambo> documentation
("MatchboxRambo implements RAMBO phase space generation.");
static Switch<MatchboxRambo,bool> interfaceMakeReferenceSample
("MakeReferenceSample",
"Switch on generation of a reference sample of phase space points.",
&MatchboxRambo::theMakeReferenceSample, false, false, false);
static SwitchOption interfaceMakeReferenceSampleYes
(interfaceMakeReferenceSample,
"Yes",
"Generate a reference sample.",
true);
static SwitchOption interfaceMakeReferenceSampleNo
(interfaceMakeReferenceSample,
"No",
"Do not generate a reference sample.",
false);
interfaceMakeReferenceSample.rank(-1);
}
diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxRambo.h b/MatrixElement/Matchbox/Phasespace/MatchboxRambo.h
--- a/MatrixElement/Matchbox/Phasespace/MatchboxRambo.h
+++ b/MatrixElement/Matchbox/Phasespace/MatchboxRambo.h
@@ -1,188 +1,180 @@
// -*- C++ -*-
//
// MatchboxRambo.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxRambo_H
#define Herwig_MatchboxRambo_H
//
// This is the declaration of the MatchboxRambo class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxRambo implements RAMBO phase space generation.
*
*/
class MatchboxRambo: public MatchboxPhasespace {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxRambo();
- /**
- * The destructor.
- */
- virtual ~MatchboxRambo();
- //@}
-
public:
/**
* Prepare a phase space generator for the given xcomb object.
*/
virtual void setXComb(tStdXCombPtr);
/**
* Generate a phase space point and return its weight.
*/
virtual double generateTwoToNKinematics(const double*,
vector<Lorentz5Momentum>& momenta);
/**
* Return the number of random numbers required to produce a given
* multiplicity final state.
*/
virtual int nDimPhasespace(int nFinal) const {
if ( nFinal == 1 )
return 1;
return 4*nFinal;
}
protected:
/**
* The function object defining the equation
* to be solved.
*/
struct ReshuffleEquation {
typedef double ArgType;
typedef Energy ValType;
static double aUnit() { return 1.; }
static Energy vUnit() { return 1.*GeV; }
Energy operator() (double xi) const;
Energy w;
cPDVector::const_iterator dataBegin;
cPDVector::const_iterator dataEnd;
vector<Lorentz5Momentum>::const_iterator momentaBegin;
vector<Lorentz5Momentum>::const_iterator momentaEnd;
ReshuffleEquation(Energy q,
cPDVector::const_iterator dBegin,
cPDVector::const_iterator dEnd,
vector<Lorentz5Momentum>::const_iterator mBegin,
vector<Lorentz5Momentum>::const_iterator mEnd)
: w(q),
dataBegin(dBegin), dataEnd(dEnd),
momentaBegin(mBegin),
momentaEnd(mEnd) {}
};
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.
*/
MatchboxRambo & operator=(const MatchboxRambo &) = delete;
/**
* Whether or not we need to reshuffle.
*/
bool needToReshuffle;
/**
* True, if a reference sample of phasespace points should be
* generated.
*/
bool theMakeReferenceSample;
/**
* Map processes to streams for reference samples
*/
map<cPDVector,ofstream*> referenceSamples;
/**
* The stream to fill for the reference sample
*/
ofstream* referenceSample;
/**
* Write the generated point to the reference sample
*/
void dumpReference(const vector<Lorentz5Momentum>&, double) const;
};
}
#endif /* Herwig_MatchboxRambo_H */
diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxReference.cc b/MatrixElement/Matchbox/Phasespace/MatchboxReference.cc
--- a/MatrixElement/Matchbox/Phasespace/MatchboxReference.cc
+++ b/MatrixElement/Matchbox/Phasespace/MatchboxReference.cc
@@ -1,105 +1,100 @@
// -*- C++ -*-
//
// MatchboxReference.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxReference class.
//
#include "MatchboxReference.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig/Utilities/GSLBisection.h"
#include "ThePEG/Cuts/Cuts.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-MatchboxReference::MatchboxReference() {}
-
-MatchboxReference::~MatchboxReference() {}
-
IBPtr MatchboxReference::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxReference::fullclone() const {
return new_ptr(*this);
}
double MatchboxReference::generateTwoToNKinematics(const double*,
vector<Lorentz5Momentum>& momenta) {
map<cPDVector,ifstream*>::iterator ref =
referenceSamples.find(mePartonData());
if ( ref == referenceSamples.end() ) {
ostringstream refname;
for ( cPDVector::const_iterator p = mePartonData().begin();
p != mePartonData().end(); ++p ) {
refname << (**p).PDGName();
}
refname << ".rambo";
referenceSamples[mePartonData()] = new ifstream(refname.str().c_str());
ref = referenceSamples.find(mePartonData());
}
assert(ref != referenceSamples.end());
ifstream& in = *(ref->second);
assert(in);
double x1,x2;
double x,y,z,t,m;
double weight;
in >> x1 >> x2;
for ( vector<Lorentz5Momentum>::iterator p = momenta.begin();
p != momenta.end(); ++p ) {
in >> x >> y >> z >> t >> m;
*p = Lorentz5Momentum(x*GeV,y*GeV,z*GeV,t*GeV,m*GeV);
}
in >> weight;
lastXCombPtr()->lastX1X2(make_pair(x1,x2));
lastXCombPtr()->lastSHat((momenta[0]+momenta[1]).m2());
return weight;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxReference::persistentOutput(PersistentOStream &) const {}
void MatchboxReference::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxReference,MatchboxPhasespace>
describeHerwigMatchboxReference("Herwig::MatchboxReference", "Herwig.so");
void MatchboxReference::Init() {
static ClassDocumentation<MatchboxReference> documentation
("MatchboxReference implements reference sample phase space generation.");
}
diff --git a/MatrixElement/Matchbox/Phasespace/MatchboxReference.h b/MatrixElement/Matchbox/Phasespace/MatchboxReference.h
--- a/MatrixElement/Matchbox/Phasespace/MatchboxReference.h
+++ b/MatrixElement/Matchbox/Phasespace/MatchboxReference.h
@@ -1,140 +1,125 @@
// -*- C++ -*-
//
// MatchboxReference.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxReference_H
#define Herwig_MatchboxReference_H
//
// This is the declaration of the MatchboxReference class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxReference implements reference sample phase space generation.
*
*/
class MatchboxReference: public MatchboxPhasespace {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- MatchboxReference();
-
- /**
- * The destructor.
- */
- virtual ~MatchboxReference();
- //@}
-
-public:
-
/**
* Generate a phase space point and return its weight.
*/
virtual double generateTwoToNKinematics(const double*,
vector<Lorentz5Momentum>& momenta);
/**
* Return the number of random numbers required to produce a given
* multiplicity final state.
*/
virtual int nDimPhasespace(int nFinal) const {
if ( nFinal == 1 )
return 1;
return 4*nFinal + 2;
}
/**
* Return true, if this phase space generator will generate incoming
* partons itself.
*/
virtual bool haveX1X2() const { return true; }
/**
* Return true, if this phase space generator expects
* the incoming partons in their center-of-mass system
*/
virtual bool wantCMS() const { return false; }
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.
*/
MatchboxReference & operator=(const MatchboxReference &) = delete;
/**
* Stream to read the reference samples.
*/
map<cPDVector,ifstream*> referenceSamples;
};
}
#endif /* Herwig_MatchboxReference_H */
diff --git a/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.cc b/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.cc
--- a/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.cc
+++ b/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.cc
@@ -1,77 +1,71 @@
// -*- C++ -*-
//
// PhasespaceCouplings.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 PhasespaceCouplings class.
//
#include "PhasespaceCouplings.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-PhasespaceCouplings::PhasespaceCouplings() {}
-
-PhasespaceCouplings::~PhasespaceCouplings() {}
-
IBPtr PhasespaceCouplings::clone() const {
return new_ptr(*this);
}
IBPtr PhasespaceCouplings::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void PhasespaceCouplings::persistentOutput(PersistentOStream & os) const {
os << theCouplings.size();
for ( map<LTriple,double>::const_iterator cit =
theCouplings.begin(); cit != theCouplings.end(); ++cit )
os << cit->first << cit->second;
}
void PhasespaceCouplings::persistentInput(PersistentIStream & is, int) {
theCouplings.clear();
size_t size;
LTriple k;
is >> size;
while ( size-- && is ) {
is >> k;
is >> theCouplings[k];
}
}
// *** 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<PhasespaceCouplings,HandlerBase>
describeHerwigPhasespaceCouplings("Herwig::PhasespaceCouplings", "Herwig.so");
void PhasespaceCouplings::Init() {
static ClassDocumentation<PhasespaceCouplings> documentation
("Store couplings for the phase space generator.");
}
diff --git a/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.h b/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.h
--- a/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.h
+++ b/MatrixElement/Matchbox/Phasespace/PhasespaceCouplings.h
@@ -1,139 +1,124 @@
// -*- C++ -*-
//
// PhasespaceCouplings.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_PhasespaceCouplings_H
#define Herwig_PhasespaceCouplings_H
//
// This is the declaration of the PhasespaceCouplings class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
namespace Herwig {
using namespace ThePEG;
typedef std::tuple<long,long,long> LTriple;
inline PersistentOStream& operator<<(PersistentOStream& os, const LTriple& t) {
os << std::get<0>(t) << std::get<1>(t) << std::get<2>(t);
return os;
}
inline PersistentIStream& operator>>(PersistentIStream& is, LTriple& t) {
is >> std::get<0>(t) >> std::get<1>(t) >> std::get<2>(t);
return is;
}
/**
*
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief Store couplings for the phase space generator.
*
* @see \ref PhasespaceCouplingsInterfaces "The interfaces"
* defined for PhasespaceCouplings.
*/
class PhasespaceCouplings: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- PhasespaceCouplings();
-
- /**
- * The destructor.
- */
- virtual ~PhasespaceCouplings();
- //@}
-
-public:
-
/**
* Couplings to be used in diagram weighting
*/
map<LTriple,double>& couplings() { return theCouplings; }
/**
* Couplings to be used in diagram weighting
*/
const map<LTriple,double>& couplings() const { return theCouplings; }
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:
/**
* Couplings to be used in diagram weighting
*/
map<LTriple,double> theCouplings;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
PhasespaceCouplings & operator=(const PhasespaceCouplings &) = delete;
};
}
#endif /* Herwig_PhasespaceCouplings_H */
diff --git a/MatrixElement/Matchbox/Phasespace/TildeKinematics.cc b/MatrixElement/Matchbox/Phasespace/TildeKinematics.cc
--- a/MatrixElement/Matchbox/Phasespace/TildeKinematics.cc
+++ b/MatrixElement/Matchbox/Phasespace/TildeKinematics.cc
@@ -1,78 +1,72 @@
// -*- C++ -*-
//
// TildeKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 TildeKinematics class.
//
#include "TildeKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Utilities/Rebinder.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-TildeKinematics::TildeKinematics()
- : HandlerBase() {}
-
-TildeKinematics::~TildeKinematics() {}
-
Energy TildeKinematics::lastScale() const {
if ( ( theDipole->bornEmitter() < 2 && theDipole->bornSpectator() > 1 ) ||
( theDipole->bornEmitter() > 1 && theDipole->bornSpectator() < 2 ) ) {
return -(bornEmitterMomentum()-bornSpectatorMomentum()).m();
}
return (bornEmitterMomentum()+bornSpectatorMomentum()).m();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void TildeKinematics::rebind(const TranslationMap & trans) {
theDipole = trans.translate(theDipole);
HandlerBase::rebind(trans);
}
IVector TildeKinematics::getReferences() {
IVector ret = HandlerBase::getReferences();
ret.push_back(theDipole);
return ret;
}
void TildeKinematics::persistentOutput(PersistentOStream & os) const {
os << theDipole << theRealXComb << theBornXComb
<< ounit(theBornEmitterMomentum,GeV) << ounit(theBornSpectatorMomentum,GeV);
}
void TildeKinematics::persistentInput(PersistentIStream & is, int) {
is >> theDipole >> theRealXComb >> theBornXComb
>> iunit(theBornEmitterMomentum,GeV) >> iunit(theBornSpectatorMomentum,GeV);
}
void TildeKinematics::Init() {
static ClassDocumentation<TildeKinematics> documentation
("TildeKinematics is the base class for the 'tilde' "
"kinematics being used for subtraction terms in the "
"formalism of Catani and Seymour.");
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeAbstractClass<TildeKinematics,HandlerBase>
describeTildeKinematics("Herwig::TildeKinematics", "Herwig.so");
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,384 +1,369 @@
// -*- C++ -*-
//
// TildeKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 pt associated to emitter emission and sppectator momentum.
*/
virtual Energy lastPt(Lorentz5Momentum,Lorentz5Momentum,Lorentz5Momentum) const =0 ;
/**
* Given a pt and a hard pt, return the boundaries on z;
*/
virtual pair<double,double> zBounds(Energy pt, Energy hardPt ) 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;
virtual bool aboveAlpha() const {
cerr<<"only implemented for light kinematics";
assert(false);
return false;
}
/**
* 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:
/**
* Return the momentum fraction of the emitter
*/
double emitterX() const {
return
theDipole->bornEmitter() == 0 ?
theBornXComb->lastX1() :
theBornXComb->lastX2();
}
/**
* Return the momentum fraction of the spectator
*/
double spectatorX() const {
return
theDipole->bornSpectator() == 0 ?
theBornXComb->lastX1() :
theBornXComb->lastX2();
}
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 &) = delete;
};
}
#endif /* HERWIG_TildeKinematics_H */
diff --git a/MatrixElement/Matchbox/Phasespace/TreePhasespace.cc b/MatrixElement/Matchbox/Phasespace/TreePhasespace.cc
--- a/MatrixElement/Matchbox/Phasespace/TreePhasespace.cc
+++ b/MatrixElement/Matchbox/Phasespace/TreePhasespace.cc
@@ -1,234 +1,232 @@
// -*- C++ -*-
//
// TreePhasespace.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 TreePhasespace class.
//
#include <sstream>
#include <string>
#include "TreePhasespace.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig/MatrixElement/Matchbox/Utility/DiagramDrawer.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
using namespace Herwig::PhasespaceHelpers;
TreePhasespace::TreePhasespace()
: x0(0.01), xc(1e-4), M0(ZERO), Mc(ZERO) {
lastPhasespaceInfo.x0 = x0;
lastPhasespaceInfo.xc = xc;
lastPhasespaceInfo.M0 = M0;
lastPhasespaceInfo.Mc = Mc;
theIncludeMirrored = true;
}
-TreePhasespace::~TreePhasespace() {}
-
IBPtr TreePhasespace::clone() const {
return new_ptr(*this);
}
IBPtr TreePhasespace::fullclone() const {
return new_ptr(*this);
}
void TreePhasespace::setXComb(tStdXCombPtr xco) {
MatchboxPhasespace::setXComb(xco);
lastChannelsIterator = channelMap().find(lastXCombPtr());
if ( lastChannelsIterator == channelMap().end() ) {
map<Ptr<Tree2toNDiagram>::ptr,pair<PhasespaceTree, PhasespaceTree> > channels;
for ( auto const & d : lastXComb().diagrams()) {
PhasespaceTree tree;
Ptr<Tree2toNDiagram>::ptr diag =
dynamic_ptr_cast<Ptr<Tree2toNDiagram>::ptr>(d);
tree.setup(*diag);
PhasespaceTree treeMirror;
treeMirror.setupMirrored(*diag, diag->nSpace() - 1);
channels[diag] = make_pair(tree,treeMirror);
}
channelMap()[lastXCombPtr()] = channels;
lastChannelsIterator = channelMap().find(lastXCombPtr());
}
}
double TreePhasespace::generateTwoToNKinematics(const double* random,
vector<Lorentz5Momentum>& momenta) {
lastPhasespaceInfo.sHat = lastXComb().lastSHat();
lastPhasespaceInfo.sqrtSHat = sqrt(lastXComb().lastSHat());
lastPhasespaceInfo.weight = 1.;
size_t nchannels = lastXComb().diagrams().size();
bool doMirror = (UseRandom::rnd() < 0.5) && theIncludeMirrored;
map<Ptr<Tree2toNDiagram>::ptr,
pair <PhasespaceHelpers::PhasespaceTree, PhasespaceHelpers::PhasespaceTree> >::iterator ds =
lastChannels().begin();
size_t i = (size_t)(random[0]*nchannels);
advance(ds,i);
Ptr<Tree2toNDiagram>::ptr channel = ds->first;
++random;
lastPhasespaceInfo.rnd.numbers = random;
lastPhasespaceInfo.rnd.nRnd = 3*momenta.size() - 10;
try {
if ( !doMirror )
lastChannels()[channel].first.generateKinematics(lastPhasespaceInfo,momenta);
else
lastChannels()[channel].second.generateKinematics(lastPhasespaceInfo,momenta);
} catch (Veto) {
return 0.;
}
if ( !matchConstraints(momenta) )
return 0.;
double flatCut = x0;
if ( M0 != ZERO )
flatCut = M0/sqrt(lastSHat());
fillDiagramWeights(flatCut);
double sum = 0.;
for ( auto const & d : lastChannels())
sum += diagramWeight(*(d.first));
double piWeight = pow(2.*Constants::pi,(double)(3*(momenta.size()-2)-4));
for ( auto & k : momenta )
k.rescaleRho();
return nchannels*lastPhasespaceInfo.weight*diagramWeight(*channel)/(sum*piWeight);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void TreePhasespace::doinit() {
MatchboxPhasespace::doinit();
lastPhasespaceInfo.x0 = x0;
lastPhasespaceInfo.xc = xc;
lastPhasespaceInfo.M0 = M0;
lastPhasespaceInfo.Mc = Mc;
}
void TreePhasespace::doinitrun() {
MatchboxPhasespace::doinitrun();
lastPhasespaceInfo.x0 = x0;
lastPhasespaceInfo.xc = xc;
lastPhasespaceInfo.M0 = M0;
lastPhasespaceInfo.Mc = Mc;
}
void TreePhasespace::persistentOutput(PersistentOStream & os) const {
os << theChannelMap << x0 << xc
<< ounit(M0,GeV) << ounit(Mc,GeV)
<< theIncludeMirrored
<< theLastXComb;
}
void TreePhasespace::persistentInput(PersistentIStream & is, int) {
is >> theChannelMap >> x0 >> xc
>> iunit(M0,GeV) >> iunit(Mc,GeV)
>> theIncludeMirrored
>> theLastXComb;
lastPhasespaceInfo.x0 = x0;
lastPhasespaceInfo.xc = xc;
lastPhasespaceInfo.M0 = M0;
lastPhasespaceInfo.Mc = Mc;
lastChannelsIterator = channelMap().find(lastXCombPtr());
}
// *** 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<TreePhasespace,MatchboxPhasespace>
describeHerwigTreePhasespace("Herwig::TreePhasespace", "Herwig.so");
void TreePhasespace::Init() {
static ClassDocumentation<TreePhasespace> documentation
("TreePhasespace is a multi-channel phase space generator "
"adapting to singularity structures as determined from the matrix "
"elements diagrams.");
static Reference<TreePhasespace,TreePhasespaceChannels> interfaceChannelMap
("ChannelMap",
"Set the object storing the channels.",
&TreePhasespace::theChannelMap, false, false, true, false, false);
interfaceChannelMap.rank(-1);
static Parameter<TreePhasespace,double> interfaceX0
("X0",
"Set the cut below which flat virtuality sampling is imposed.",
&TreePhasespace::x0, 0.01, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<TreePhasespace,double> interfaceXC
("XC",
"Set the cut below which no virtualities are generated.",
&TreePhasespace::xc, 1e-4, 0.0, 0,
false, false, Interface::lowerlim);
static Parameter<TreePhasespace,Energy> interfaceM0
("M0",
"Set the cut below which flat virtuality sammpling is imposed.",
&TreePhasespace::M0, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<TreePhasespace,Energy> interfaceMC
("MC",
"Set the cut below which no virtualities are generated.",
&TreePhasespace::Mc, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Switch<TreePhasespace,bool> interfaceIncludeMirrored
("IncludeMirrored",
"Choose whether to include mirrored diagrams for PS generation",
&TreePhasespace::theIncludeMirrored, true, true, false);
static SwitchOption interfaceIncludeMirroredYes
(interfaceIncludeMirrored,
"Yes",
"Use unmirrored and mirrored diagrams",
true);
static SwitchOption interfaceIncludeMirroredNo
(interfaceIncludeMirrored,
"No",
"Use only unmirrored diagrams",
false);
interfaceIncludeMirrored.rank(-1);
}
diff --git a/MatrixElement/Matchbox/Phasespace/TreePhasespace.h b/MatrixElement/Matchbox/Phasespace/TreePhasespace.h
--- a/MatrixElement/Matchbox/Phasespace/TreePhasespace.h
+++ b/MatrixElement/Matchbox/Phasespace/TreePhasespace.h
@@ -1,217 +1,209 @@
// -*- C++ -*-
//
// TreePhasespace.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_TreePhasespace_H
#define Herwig_TreePhasespace_H
//
// This is the declaration of the TreePhasespace class.
//
#include "Herwig/MatrixElement/Matchbox/Phasespace/MatchboxPhasespace.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer, Ken Arnold
*
* \brief TreePhasespace is a multi-channel phase space generator
* adapting to singularity structures as determined from the matrix
* elements diagrams.
*
* @see \ref TreePhasespaceInterfaces "The interfaces"
* defined for TreePhasespace.
*/
class TreePhasespace: public MatchboxPhasespace {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
TreePhasespace();
- /**
- * The destructor.
- */
- virtual ~TreePhasespace();
- //@}
-
public:
/**
* Prepare a phase space generator for the given xcomb object.
*/
virtual void setXComb(tStdXCombPtr);
/**
* Generate a phase space point and return its weight.
*/
virtual double generateTwoToNKinematics(const double*,
vector<Lorentz5Momentum>& momenta);
/**
* Return the number of random numbers required to produce a given
* multiplicity final state.
*/
virtual int nDimPhasespace(int nFinal) const {
if ( nFinal == 1 )
return 1;
return 3*(nFinal - 1); // one additional number needed for channel selection
}
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();
//@}
private:
/**
* The object storing channel maps
*/
Ptr<TreePhasespaceChannels>::ptr theChannelMap;
/**
* Map xcomb's to channel vectors indexed by diagram id.
*/
map<tStdXCombPtr,
map<Ptr<Tree2toNDiagram>::ptr,
pair <PhasespaceHelpers::PhasespaceTree, PhasespaceHelpers::PhasespaceTree> > >&
channelMap() { return theChannelMap->channelMap(); }
/**
* The currently active channels.
*/
map<tStdXCombPtr,
map<Ptr<Tree2toNDiagram>::ptr,
pair <PhasespaceHelpers::PhasespaceTree, PhasespaceHelpers::PhasespaceTree> > >::iterator
lastChannelsIterator;
/**
* The phase space info object to be used.
*/
PhasespaceHelpers::PhasespaceInfo lastPhasespaceInfo;
/**
* Parameter steering from which on propagator virtualities are
* sampled flat.
*/
double x0;
/**
* Parameter steering at which virtuality singularities of
* propagators are actually cut off.
*/
double xc;
/**
* Parameter steering from which on propagator virtualities are
* sampled flat.
*/
Energy M0;
/**
* Parameter steering at which virtuality singularities of
* propagators are actually cut off.
*/
Energy Mc;
/**
* Choose whether to also use mirrored phase space generation
*/
bool theIncludeMirrored;
/**
* Return the currently active channels.
*/
map<Ptr<Tree2toNDiagram>::ptr,
pair <PhasespaceHelpers::PhasespaceTree, PhasespaceHelpers::PhasespaceTree> >& lastChannels() {
return lastChannelsIterator->second;
}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
TreePhasespace & operator=(const TreePhasespace &) = delete;
};
}
#endif /* Herwig_TreePhasespace_H */
diff --git a/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.cc b/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.cc
--- a/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.cc
+++ b/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.cc
@@ -1,89 +1,83 @@
// -*- C++ -*-
//
// TreePhasespaceChannels.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 TreePhasespaceChannels class.
//
#include "TreePhasespaceChannels.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
-
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
using namespace Herwig::PhasespaceHelpers;
-TreePhasespaceChannels::TreePhasespaceChannels() {}
-
-TreePhasespaceChannels::~TreePhasespaceChannels() {}
-
IBPtr TreePhasespaceChannels::clone() const {
return new_ptr(*this);
}
IBPtr TreePhasespaceChannels::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void TreePhasespaceChannels::persistentOutput(PersistentOStream & os) const {
os << theChannelMap.size();
for ( map<tStdXCombPtr,map<Ptr<Tree2toNDiagram>::ptr,pair <PhasespaceTree,PhasespaceTree> > >::const_iterator k =
theChannelMap.begin(); k != theChannelMap.end(); ++k ) {
os << k->first << k->second.size();
for ( map<Ptr<Tree2toNDiagram>::ptr,pair <PhasespaceTree,PhasespaceTree> >::const_iterator l =
k->second.begin(); l != k->second.end(); ++l ) {
os << l->first;
l->second.first.put(os);
l->second.second.put(os);
}
}
}
void TreePhasespaceChannels::persistentInput(PersistentIStream & is, int) {
size_t nk; is >> nk;
for ( size_t k = 0; k < nk; ++k ) {
tStdXCombPtr xc; is >> xc;
size_t nl; is >> nl;
map<Ptr<Tree2toNDiagram>::ptr,pair <PhasespaceTree,PhasespaceTree> > cm;
for ( size_t l = 0; l < nl; ++l ) {
Ptr<Tree2toNDiagram>::ptr ci; is >> ci;
pair<PhasespaceTree,PhasespaceTree> cp; cp.first.get(is); cp.second.get(is);
cm[ci] = cp;
}
theChannelMap[xc] = cm;
}
}
// *** 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<TreePhasespaceChannels,HandlerBase>
describeHerwigTreePhasespaceChannels("Herwig::TreePhasespaceChannels", "Herwig.so");
void TreePhasespaceChannels::Init() {
static ClassDocumentation<TreePhasespaceChannels> documentation
("Store channels for the tree phase space.");
}
diff --git a/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.h b/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.h
--- a/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.h
+++ b/MatrixElement/Matchbox/Phasespace/TreePhasespaceChannels.h
@@ -1,128 +1,113 @@
// -*- C++ -*-
//
// TreePhasespaceChannels.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_TreePhasespaceChannels_H
#define Herwig_TreePhasespaceChannels_H
//
// This is the declaration of the TreePhasespaceChannels class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/PhasespaceHelpers.h"
namespace Herwig {
using namespace ThePEG;
/**
*
* \ingroup Matchbox
* \author Simon Platzer, Ken Arnold
*
* \brief Store channels for the tree phasespace.
*
* @see \ref TreePhasespaceChannelsInterfaces "The interfaces"
* defined for TreePhasespaceChannels.
*/
class TreePhasespaceChannels: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- TreePhasespaceChannels();
-
- /**
- * The destructor.
- */
- virtual ~TreePhasespaceChannels();
- //@}
-
-public:
-
/**
* Access the channel map
*/
map<tStdXCombPtr,map<Ptr<Tree2toNDiagram>::ptr,pair <PhasespaceHelpers::PhasespaceTree, PhasespaceHelpers::PhasespaceTree> > >&
channelMap() { return theChannelMap; }
/**
* Return the channel map
*/
const map<tStdXCombPtr,map<Ptr<Tree2toNDiagram>::ptr,pair <PhasespaceHelpers::PhasespaceTree, PhasespaceHelpers::PhasespaceTree> > >&
channelMap() const { return theChannelMap; }
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:
/**
* Map xcomb's to channel vectors indexed by diagram id.
*/
map<tStdXCombPtr,map<Ptr<Tree2toNDiagram>::ptr,pair<PhasespaceHelpers::PhasespaceTree,PhasespaceHelpers::PhasespaceTree> > > theChannelMap;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
TreePhasespaceChannels & operator=(const TreePhasespaceChannels &) = delete;
};
}
#endif /* Herwig_TreePhasespaceChannels_H */
diff --git a/MatrixElement/Matchbox/Tests/HardProcessAnalysis.cc b/MatrixElement/Matchbox/Tests/HardProcessAnalysis.cc
--- a/MatrixElement/Matchbox/Tests/HardProcessAnalysis.cc
+++ b/MatrixElement/Matchbox/Tests/HardProcessAnalysis.cc
@@ -1,433 +1,429 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the HardProcessAnalysis class.
//
#include "HardProcessAnalysis.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/EventRecord/SubProcess.h"
#include "ThePEG/EventRecord/SubProcessGroup.h"
#include "ThePEG/Handlers/EventHandler.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
HardProcessAnalysis::HardProcessAnalysis()
: sumWeights(0.0), theNBins(100), theUnitWeights(false),
theSplitInitialStates(true),
thePartonsAreJets(false) {}
-HardProcessAnalysis::~HardProcessAnalysis() {}
-
-
-
#ifndef LWH_AIAnalysisFactory_H
#ifndef LWH
#define LWH ThePEGLWH
#endif
#include "ThePEG/Analysis/LWH/AnalysisFactory.h"
#endif
HardProcessAnalysis::Histograms::Histograms(Energy ECM, unsigned int theNBins) {
vector<double> logBins(theNBins+1);
double logLow = 1.0;
double logUp = ECM/GeV/4.;
double cLog = log10(logUp/logLow)/theNBins;
for ( size_t k = 0; k < theNBins+1; ++k )
logBins[k] = logLow*pow(10.0,cLog*k);
transverse = new_ptr(Histogram(logBins));
rapidity = new_ptr(Histogram(-7.,7.,theNBins));
phi = new_ptr(Histogram(-Constants::pi,Constants::pi,theNBins));
}
void HardProcessAnalysis::Histograms::fill(const Lorentz5Momentum& p, double weight) {
transverse->addWeighted(p.perp()/GeV,weight);
rapidity->addWeighted(p.rapidity(),weight);
phi->addWeighted(p.phi(),weight);
}
void HardProcessAnalysis::Histograms::finalize(ostream& dat,
ostream& plot,
const string& subpro,
size_t legid,
double norm,
bool theUnitWeights) {
transverse->prefactor(norm);
rapidity->prefactor(norm);
phi->prefactor(norm);
ostringstream prefix;
prefix << subpro << "_" << legid;
plot << "# BEGIN PLOT /HardProcessAnalysis" << (!theUnitWeights ? "" : "Flat") << "/"
<< prefix.str() << "_transverse\n"
<< "Title=Transverse momentum of " << prefix.str() << "\n"
<< "XLabel=" << "$p_\\perp$/GeV" << "\n"
<< "YLabel=" << "${\\rm d}\\sigma/{\\rm d}p_\\perp$/(nb/GeV)" << "\n"
<< "LogX=1\n"
<< "LogY=0\n"
<< "# END PLOT\n\n";
transverse->rivetOutput(dat,prefix.str() + "_transverse",!theUnitWeights ? "HardProcessAnalysis" : "HardProcessAnalysisFlat");
dat << "\n";
plot << "# BEGIN PLOT /HardProcessAnalysis" << (!theUnitWeights ? "" : "Flat") << "/"
<< prefix.str() << "_rapidity\n"
<< "Title=Rapidity of " << prefix.str() << "\n"
<< "XLabel=" << "$y$" << "\n"
<< "YLabel=" << "${\\rm d}\\sigma/{\\rm d}y$/nb" << "\n"
<< "LogX=0\n"
<< "LogY=0\n"
<< "# END PLOT\n\n";
rapidity->rivetOutput(dat,prefix.str() + "_rapidity",!theUnitWeights ? "HardProcessAnalysis" : "HardProcessAnalysisFlat");
dat << "\n";
plot << "# BEGIN PLOT /HardProcessAnalysis" << (!theUnitWeights ? "" : "Flat") << "/"
<< prefix.str() << "_phi\n"
<< "Title=Azimuthal angle of " << prefix.str() << "\n"
<< "XLabel=" << "$\\phi$" << "\n"
<< "YLabel=" << "${\\rm d}\\sigma/{\\rm d}\\phi$/nb" << "\n"
<< "LogX=0\n"
<< "LogY=0\n"
<< "# END PLOT\n\n";
phi->rivetOutput(dat,prefix.str() + "_phi",!theUnitWeights ? "HardProcessAnalysis" : "HardProcessAnalysisFlat");
dat << "\n";
}
struct SortedInPt {
bool partonsAreJets;
explicit SortedInPt(bool newPartonsAreJets = false)
: partonsAreJets(newPartonsAreJets) {}
inline bool operator()(PPtr a, PPtr b) const {
long aId = a->id();
if ( partonsAreJets && a->coloured() )
aId = 21;
long bId = b->id();
if ( partonsAreJets && b->coloured() )
bId = 21;
if ( aId != bId )
return ( aId < bId );
return a->momentum().perp() > b->momentum().perp();
}
};
struct GetName {
bool partonsAreJets;
explicit GetName(bool newPartonsAreJets = false)
: partonsAreJets(newPartonsAreJets) {}
inline string operator()(PPtr p) const {
if ( partonsAreJets && p->coloured() )
return "j";
string res = p->PDGName();
string::size_type pos = res.find("+");
while ( pos != string::npos ) {
res.replace(pos,1,"plus");
pos = res.find("+");
}
pos = res.find("-");
while ( pos != string::npos ) {
res.replace(pos,1,"minus");
pos = res.find("-");
}
return res;
}
};
void HardProcessAnalysis::fill(PPair in, ParticleVector out, double weight) {
sort(out.begin(),out.end(),SortedInPt(thePartonsAreJets));
vector<string> proc;
if ( theSplitInitialStates ) {
proc.push_back(GetName()(in.first));
proc.push_back(GetName()(in.second));
}
std::transform(out.begin(),out.end(),
back_inserter(proc),GetName(thePartonsAreJets));
AllHistograms& data = histogramData[proc];
if ( data.outgoing.empty() ) {
for ( size_t k = 0; k < out.size(); ++k )
data.outgoing.push_back(Histograms(generator()->maximumCMEnergy(),theNBins));
vector<double> logBins(theNBins+1);
double logLow = 1.0e-6;
double logUp = 1.0;
double cLog = log10(logUp/logLow)/theNBins;
for ( size_t k = 0; k < theNBins+1; ++k )
logBins[k] = logLow*pow(10.0,cLog*k);
data.x1 = new_ptr(Histogram(logBins));
data.x2 = new_ptr(Histogram(logBins));
logUp = generator()->maximumCMEnergy()/GeV;
logLow = 1.0;
cLog = log10(logUp/logLow)/theNBins;
for ( size_t k = 0; k < theNBins+1; ++k )
logBins[k] = logLow*pow(10.0,cLog*k);
data.sshat = new_ptr(Histogram(logBins));
data.rapidity = new_ptr(Histogram(-7.,7.,theNBins));
data.sumWeights = 0.;
}
bool twoIdentical = false;
if ( out.size() == 2 ) {
if ( out[0]->id() == out[1]->id() ||
(out[0]->coloured() && out[1]->coloured() && thePartonsAreJets) )
twoIdentical = true;
}
if ( !twoIdentical ) {
ParticleVector::const_iterator p = out.begin();
vector<Histograms>::iterator h = data.outgoing.begin();
for ( ; p != out.end(); ++p, ++h )
h->fill((**p).momentum(),weight);
} else {
data.outgoing[0].fill(out[0]->momentum(),weight/2.);
data.outgoing[0].fill(out[1]->momentum(),weight/2.);
data.outgoing[1].fill(out[0]->momentum(),weight/2.);
data.outgoing[1].fill(out[1]->momentum(),weight/2.);
}
double y = (in.first->momentum() + in.second->momentum()).rapidity();
data.rapidity->addWeighted(y,weight);
Energy2 shat = (in.first->momentum() + in.second->momentum()).m2();
data.sshat->addWeighted(sqrt(shat)/GeV,weight);
double tau = shat/sqr(generator()->maximumCMEnergy());
double x1 = sqrt(tau)*exp(y);
double x2 = sqrt(tau)*exp(-y);
data.x1->addWeighted(x1,weight);
data.x2->addWeighted(x2,weight);
data.sumWeights += weight;
}
void HardProcessAnalysis::analyze(tEventPtr event, long ieve, int loop, int state) {
AnalysisHandler::analyze(event, ieve, loop, state);
tSubProPtr sub = event->primarySubProcess();
Ptr<SubProcessGroup>::tptr grp =
dynamic_ptr_cast<Ptr<SubProcessGroup>::tptr>(sub);
double weight = !theUnitWeights ? event->weight()*sub->groupWeight() : 1.0;
sumWeights += weight;
fill(sub->incoming(),sub->outgoing(),weight);
if ( grp ) {
for ( SubProcessVector::const_iterator s = grp->dependent().begin();
s != grp->dependent().end(); ++s ) {
weight = !theUnitWeights ? event->weight()*(**s).groupWeight() : 1.0;
fill((**s).incoming(),(**s).outgoing(),weight);
}
}
}
void HardProcessAnalysis::dofinish() {
AnalysisHandler::dofinish();
ofstream dat(!theUnitWeights ? "HardProcessAnalysis.dat" : "HardProcessAnalysisFlat.dat");
ofstream plot(!theUnitWeights ? "HardProcessAnalysis.plot" : "HardProcessAnalysisFlat.plot");
for ( map<vector<string>,AllHistograms>::iterator h =
histogramData.begin(); h != histogramData.end(); ++h ) {
string subpro;
for ( vector<string>::const_iterator p = h->first.begin();
p != h->first.end(); ++p ) {
subpro += *p + (p != --(h->first.end()) ? "_" : "");
}
double fraction = h->second.sumWeights / sumWeights;
for ( size_t k = 0; k < h->second.outgoing.size(); ++k )
h->second.outgoing[k].finalize(dat,plot,subpro,k+2,
generator()->eventHandler()->integratedXSec() * fraction/nanobarn,
theUnitWeights);
h->second.x1->prefactor(generator()->eventHandler()->integratedXSec() * fraction/nanobarn);
plot << "# BEGIN PLOT /HardProcessAnalysis" << (!theUnitWeights ? "" : "Flat") << "/"
<< subpro << "_x1\n"
<< "Title=Momentum fraction of first parton in " << subpro << "\n"
<< "XLabel=" << "$x_1$" << "\n"
<< "YLabel=" << "${\\rm d}\\sigma/{\\rm d}x_1$/nb" << "\n"
<< "LogX=1\n"
<< "LogY=0\n"
<< "# END PLOT\n\n";
h->second.x1->rivetOutput(dat,subpro + "_x1",!theUnitWeights ? "HardProcessAnalysis" : "HardProcessAnalysisFlat");
dat << "\n";
h->second.x2->prefactor(generator()->eventHandler()->integratedXSec() * fraction/nanobarn);
plot << "# BEGIN PLOT /HardProcessAnalysis" << (!theUnitWeights ? "" : "Flat") << "/"
<< subpro << "_x2\n"
<< "Title=Momentum fraction of second parton in " << subpro << "\n"
<< "XLabel=" << "$x_2$" << "\n"
<< "YLabel=" << "${\\rm d}\\sigma/{\\rm d}x_2$/nb" << "\n"
<< "LogX=1\n"
<< "LogY=0\n"
<< "# END PLOT\n\n";
h->second.x2->rivetOutput(dat,subpro + "_x2",!theUnitWeights ? "HardProcessAnalysis" : "HardProcessAnalysisFlat");
dat << "\n";
h->second.rapidity->prefactor(generator()->eventHandler()->integratedXSec() * fraction/nanobarn);
plot << "# BEGIN PLOT /HardProcessAnalysis" << (!theUnitWeights ? "" : "Flat") << "/"
<< subpro << "_y\n"
<< "Title=Rapidity in " << subpro << "\n"
<< "XLabel=" << "$y$" << "\n"
<< "YLabel=" << "${\\rm d}\\sigma/{\\rm d}y$/nb" << "\n"
<< "LogX=0\n"
<< "LogY=0\n"
<< "# END PLOT\n\n";
h->second.rapidity->rivetOutput(dat,subpro + "_y",!theUnitWeights ? "HardProcessAnalysis" : "HardProcessAnalysisFlat");
dat << "\n";
h->second.sshat->prefactor(generator()->eventHandler()->integratedXSec() * fraction/nanobarn);
plot << "# BEGIN PLOT /HardProcessAnalysis" << (!theUnitWeights ? "" : "Flat") << "/"
<< subpro << "_sshat\n"
<< "Title=Partonic centre of mass energy in " << subpro << "\n"
<< "XLabel=" << "$\\sqrt{\\hat{s}}$/GeV" << "\n"
<< "YLabel=" << "${\\rm d}\\sigma/{\\rm d}\\sqrt{\\hat{s}}$/(nb/GeV)" << "\n"
<< "LogX=1\n"
<< "LogY=0\n"
<< "# END PLOT\n\n";
h->second.sshat->rivetOutput(dat,subpro + "_sshat",!theUnitWeights ? "HardProcessAnalysis" : "HardProcessAnalysisFlat");
dat << "\n";
}
Energy ECM = generator()->maximumCMEnergy();
CrossSection xsec = generator()->eventHandler()->integratedXSec();
CrossSection xsecErr = generator()->eventHandler()->integratedXSecErr();
dat << "# BEGIN HISTOGRAM /"
<< (!theUnitWeights ? "HardProcessAnalysis" : "HardProcessAnalysisFlat")
<< "/xsec\n"
<< "AidaPath=/"
<< (!theUnitWeights ? "HardProcessAnalysis" : "HardProcessAnalysisFlat")
<< "/xsec\n"
<< (ECM/GeV - 10.) << "\t"
<< (ECM/GeV + 10.) << "\t"
<< (xsec/nanobarn) << "\t"
<< (xsecErr/nanobarn) << "\n"
<< "# END HISTOGRAM\n";
plot << "# BEGIN PLOT /HardProcessAnalysis" << (!theUnitWeights ? "" : "Flat") << "/xsec\n"
<< "Title=Total cross section\n"
<< "XLabel=" << "$\\sqrt{S}$/GeV" << "\n"
<< "YLabel=" << "$\\sigma(\\sqrt(S))$/nb" << "\n"
<< "LogX=0\n"
<< "LogY=0\n"
<< "# END PLOT\n\n";
}
void HardProcessAnalysis::doinitrun() {
AnalysisHandler::doinitrun();
// *** ATTENTION *** histogramFactory().registerClient(this); // Initialize histograms.
// *** ATTENTION *** histogramFactory().mkdirs("/SomeDir"); // Put histograms in specal directory.
}
IBPtr HardProcessAnalysis::clone() const {
return new_ptr(*this);
}
IBPtr HardProcessAnalysis::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void HardProcessAnalysis::persistentOutput(PersistentOStream & os) const {
os << theNBins << theUnitWeights << theSplitInitialStates << thePartonsAreJets;
}
void HardProcessAnalysis::persistentInput(PersistentIStream & is, int) {
is >> theNBins >> theUnitWeights >> theSplitInitialStates >> thePartonsAreJets;
}
// *** 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<HardProcessAnalysis,AnalysisHandler>
describeHerwigHardProcessAnalysis("Herwig::HardProcessAnalysis", "Herwig.so");
void HardProcessAnalysis::Init() {
static ClassDocumentation<HardProcessAnalysis> documentation
("There is no documentation for the HardProcessAnalysis class");
static Parameter<HardProcessAnalysis,unsigned int> interfaceNBins
("NBins",
"The number of bins to use",
&HardProcessAnalysis::theNBins, 100, 1, 0,
false, false, Interface::lowerlim);
static Switch<HardProcessAnalysis,bool> interfaceUnitWeights
("UnitWeights",
"Use unit weights",
&HardProcessAnalysis::theUnitWeights, false, false, false);
static SwitchOption interfaceUnitWeightsYes
(interfaceUnitWeights,
"Yes",
"Use unit weights",
true);
static SwitchOption interfaceUnitWeightsNo
(interfaceUnitWeights,
"No",
"Do not use unit weights",
false);
static Switch<HardProcessAnalysis,bool> interfaceSplitInitialStates
("SplitInitialStates",
"Distinguish by initial state",
&HardProcessAnalysis::theSplitInitialStates, true, false, false);
static SwitchOption interfaceSplitInitialStatesYes
(interfaceSplitInitialStates,
"Yes",
"",
true);
static SwitchOption interfaceSplitInitialStatesNo
(interfaceSplitInitialStates,
"No",
"",
false);
static Switch<HardProcessAnalysis,bool> interfacePartonsAreJets
("PartonsAreJets",
"Treat each parton as a jet.",
&HardProcessAnalysis::thePartonsAreJets, false, false, false);
static SwitchOption interfacePartonsAreJetsYes
(interfacePartonsAreJets,
"Yes",
"",
true);
static SwitchOption interfacePartonsAreJetsNo
(interfacePartonsAreJets,
"No",
"",
false);
}
diff --git a/MatrixElement/Matchbox/Tests/HardProcessAnalysis.h b/MatrixElement/Matchbox/Tests/HardProcessAnalysis.h
--- a/MatrixElement/Matchbox/Tests/HardProcessAnalysis.h
+++ b/MatrixElement/Matchbox/Tests/HardProcessAnalysis.h
@@ -1,257 +1,249 @@
// -*- C++ -*-
#ifndef Herwig_HardProcessAnalysis_H
#define Herwig_HardProcessAnalysis_H
//
// This is the declaration of the HardProcessAnalysis class.
//
#include "ThePEG/Handlers/AnalysisHandler.h"
#include "Herwig/Utilities/Histogram.h"
namespace Herwig {
using namespace ThePEG;
/**
* Here is the documentation of the HardProcessAnalysis class.
*
* @see \ref HardProcessAnalysisInterfaces "The interfaces"
* defined for HardProcessAnalysis.
*/
class HardProcessAnalysis: public AnalysisHandler {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
HardProcessAnalysis();
- /**
- * The destructor.
- */
- virtual ~HardProcessAnalysis();
- //@}
-
public:
/** @name Virtual functions required by the AnalysisHandler class. */
//@{
/**
* Analyze a given Event. Note that a fully generated event
* may be presented several times, if it has been manipulated in
* between. The default version of this function will call transform
* to make a lorentz transformation of the whole event, then extract
* all final state particles and call analyze(tPVector) of this
* analysis object and those of all associated analysis objects. The
* default version will not, however, do anything on events which
* have not been fully generated, or have been manipulated in any
* way.
* @param event pointer to the Event to be analyzed.
* @param ieve the event number.
* @param loop the number of times this event has been presented.
* If negative the event is now fully generated.
* @param state a number different from zero if the event has been
* manipulated in some way since it was last presented.
*/
virtual void analyze(tEventPtr event, long ieve, int loop, int state);
//@}
protected:
/**
* 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();
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.
*/
HardProcessAnalysis & operator=(const HardProcessAnalysis &) = delete;
/**
* Differential information per outgoing parton
*/
struct Histograms {
/**
* The constructor
*/
Histograms() {}
/**
* The constructor
*/
explicit Histograms(Energy ECM, unsigned int theNBins);
/**
* Analyse given momentum
*/
void fill(const Lorentz5Momentum& p, double weight);
/**
* Finalize given process id and cross section.
*/
void finalize(ostream& dat,
ostream& plot,
const string& subpro,
size_t legid,
double norm,
bool theUnitWeights);
/**
* Pt spectrum
*/
HistogramPtr transverse;
/**
* Rapidity distribution
*/
HistogramPtr rapidity;
/**
* Azimuthal angle distribution
*/
HistogramPtr phi;
};
/**
* Outgoing partons and x distributions
*/
struct AllHistograms {
/**
* Outgoing partons
*/
vector<Histograms> outgoing;
/**
* x1 distribution
*/
HistogramPtr x1;
/**
* x2 distribution
*/
HistogramPtr x2;
/**
* sqrt(shat) distribution
*/
HistogramPtr sshat;
/**
* y distribution
*/
HistogramPtr rapidity;
/**
* The sum of weights
*/
double sumWeights;
};
/**
* Histograms per subprocess
*/
map<vector<string>,AllHistograms> histogramData;
/**
* The total sum of weights
*/
double sumWeights;
/**
* Analyze a given final state
*/
void fill(PPair, ParticleVector, double);
/**
* The number of bins to use
*/
unsigned int theNBins;
/**
* True, if unit weights should be booked
*/
bool theUnitWeights;
/**
* True, if subprocesses should be distinguished by initial state
*/
bool theSplitInitialStates;
/**
* True, if partons should be handled as jets irrespective of flavour
*/
bool thePartonsAreJets;
};
}
#endif /* Herwig_HardProcessAnalysis_H */
diff --git a/MatrixElement/Matchbox/Tests/WeightAnalyzer.cc b/MatrixElement/Matchbox/Tests/WeightAnalyzer.cc
--- a/MatrixElement/Matchbox/Tests/WeightAnalyzer.cc
+++ b/MatrixElement/Matchbox/Tests/WeightAnalyzer.cc
@@ -1,283 +1,279 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the WeightAnalyzer class.
//
#include "WeightAnalyzer.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/EventRecord/SubProcess.h"
#include "ThePEG/EventRecord/SubProcessGroup.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
WeightAnalyzer::WeightAnalyzer()
: sumWeights(0.0), sumPositiveWeights(0.0),
sumNegativeWeights(0.0),
sumGroupWeights(0.0), sumPositiveGroupWeights(0.0),
sumNegativeGroupWeights(0.0),
maxDeviationGroupWeight(0.0),
maxDeviationEventWeight(0.0),
nPositiveWeights(0.0),
nNegativeWeights(0.0),
maxPositiveWeight(0.0),
maxNegativeWeight(0.0),
gnuplot(true) {}
-WeightAnalyzer::~WeightAnalyzer(){}
-
-
-
#ifndef LWH_AIAnalysisFactory_H
#ifndef LWH
#define LWH ThePEGLWH
#endif
#include "ThePEG/Analysis/LWH/AnalysisFactory.h"
#endif
void WeightAnalyzer::analyze(tEventPtr event, long ieve, int loop, int state) {
AnalysisHandler::analyze(event, ieve, loop, state);
double weight = event->weight();
sumWeights += weight;
if ( weight > 0.0 ) {
sumPositiveWeights += weight;
maxPositiveWeight = max(maxPositiveWeight,weight);
nPositiveWeights += 1;
map<double,double>::iterator b = positiveWeightDistribution.upper_bound(weight);
if ( b != positiveWeightDistribution.end() )
b->second += 1;
else
(--positiveWeightDistribution.end())->second += 1;
}
if ( weight < 0.0 ) {
sumNegativeWeights += weight;
maxNegativeWeight = max(maxNegativeWeight,abs(weight));
nNegativeWeights += 1;
map<double,double>::iterator b = negativeWeightDistribution.upper_bound(abs(weight));
if ( b != negativeWeightDistribution.end() )
b->second += 1;
else
(--negativeWeightDistribution.end())->second += 1;
}
tSubProPtr sub = event->primarySubProcess();
Ptr<SubProcessGroup>::tptr grp =
dynamic_ptr_cast<Ptr<SubProcessGroup>::tptr>(sub);
double sumEvents = 0.0;
double sumGroups = 0.0;
sumGroupWeights += weight*sub->groupWeight();
if ( weight*sub->groupWeight() > 0.0 )
sumPositiveGroupWeights += weight*sub->groupWeight();
if ( weight*sub->groupWeight() < 0.0 )
sumNegativeGroupWeights += weight*sub->groupWeight();
sumEvents += weight*sub->groupWeight();
sumGroups += sub->groupWeight();
if ( grp ) {
for ( SubProcessVector::const_iterator s = grp->dependent().begin();
s != grp->dependent().end(); ++s ) {
sumGroupWeights += weight*(**s).groupWeight();
if ( weight*(**s).groupWeight() > 0.0 )
sumPositiveGroupWeights += weight*(**s).groupWeight();
if ( weight*(**s).groupWeight() < 0.0 )
sumNegativeGroupWeights += weight*(**s).groupWeight();
sumEvents += weight*(**s).groupWeight();
sumGroups += (**s).groupWeight();
}
}
maxDeviationGroupWeight = max(maxDeviationGroupWeight,abs(sumGroups-1));
maxDeviationEventWeight = max(maxDeviationEventWeight,abs(sumEvents/weight-1));
}
void WeightAnalyzer::dofinish() {
AnalysisHandler::dofinish();
if ( nPositiveWeights != 0 )
for ( map<double,double>::iterator b = positiveWeightDistribution.begin();
b != positiveWeightDistribution.end(); ++b ) {
b->second /= nPositiveWeights;
}
if ( nNegativeWeights != 0 )
for ( map<double,double>::iterator b = negativeWeightDistribution.begin();
b != negativeWeightDistribution.end(); ++b ) {
b->second /= nNegativeWeights;
}
string dataName = generator()->filename() + "Weights."+(gnuplot?"gp":"dat");
ofstream data(dataName.c_str());
data << setprecision(17)
<< "# --------------------------------------------------------------------------------\n"
<< "# WeightAnalyzer information\n"
<< "# --------------------------------------------------------------------------------\n"
<< "# sum of weights : " << sumWeights << "\n"
<< "# sum of positive weights : " << sumPositiveWeights << "\n"
<< "# sum of negative weights : " << sumNegativeWeights << "\n"
<< "# sum of weights (from groups) : " << sumGroupWeights << "\n"
<< "# sum of positive weights (from groups) : " << sumPositiveGroupWeights << "\n"
<< "# sum of negative weights (from groups) : " << sumNegativeGroupWeights << "\n"
<< "# maximum devation group weights : " << maxDeviationGroupWeight << "\n"
<< "# maximum devation event weights : " << maxDeviationEventWeight << "\n"
<< "# number of positive weights : " << nPositiveWeights << "\n"
<< "# number of negative weights : " << nNegativeWeights << "\n"
<< "# maximum positive weight : " << maxPositiveWeight << "\n"
<< "# maximum negative weight : " << maxNegativeWeight << "\n"
<< "# --------------------------------------------------------------------------------\n"
<< flush;
data << "\n\n";
if(gnuplot){
data << "set terminal pdf\n"
<< "set xlabel 'weights'\n"
<< "set ylabel '\n"
<< "set logscale \n"
<< "set output '" << generator()->filename()<<"Weights.pdf'\n"
<< "plot \"-\" using 2:3 with histeps lc rgbcolor \"#00AACC\" t \"positive weights\"\n"
<< "# low up val\n";
}
for ( map<double,double>::const_iterator b = positiveWeightDistribution.begin();
b != positiveWeightDistribution.end(); ++b ) {
if ( b->second != 0 ) {
double l,u;
if ( b == positiveWeightDistribution.begin() ) {
l = 0.; u = b->first;
} else if ( b == --positiveWeightDistribution.end() ) {
map<double,double>::const_iterator bl = b; --bl;
l = bl->first; u = Constants::MaxDouble;
} else {
map<double,double>::const_iterator bl = b; --bl;
l = bl->first; u = b->first;
}
data << l << " " << u << " " << b->second << "\n";
}
}
data << flush;
if(gnuplot)data<< "e";
data << "\n\n";
if(gnuplot && sumNegativeGroupWeights>0.){
data<< "plot \"-\" using 2:3 with histeps lc rgbcolor \"#00AACC\" t \"negative weights\"\n"
<< "# low up val\n";
}
for ( map<double,double>::const_iterator b = negativeWeightDistribution.begin();
b != negativeWeightDistribution.end(); ++b ) {
if ( b->second != 0 ) {
double l,u;
if ( b == negativeWeightDistribution.begin() ) {
l = 0.; u = b->first;
} else if ( b == --negativeWeightDistribution.end() ) {
map<double,double>::const_iterator bl = b; --bl;
l = bl->first; u = Constants::MaxDouble;
} else {
map<double,double>::const_iterator bl = b; --bl;
l = bl->first; u = b->first;
}
data << l << " " << u << " " << b->second << "\n";
}
}
if(gnuplot&& sumNegativeGroupWeights>0.)data<< "e";
data << flush;
}
void WeightAnalyzer::doinitrun() {
AnalysisHandler::doinitrun();
positiveWeightDistribution.clear();
negativeWeightDistribution.clear();
unsigned int nbins = 200;
nbins += 1;
double low = 1.e-8;
double up = 1.e8;
double c = log10(up/low) / (nbins-1.);
for ( unsigned int k = 1; k < nbins + 1; ++k ) { // mind the overflow bin
positiveWeightDistribution[low*pow(10.0,k*c)] = 0.;
negativeWeightDistribution[low*pow(10.0,k*c)] = 0.;
}
}
IBPtr WeightAnalyzer::clone() const {
return new_ptr(*this);
}
IBPtr WeightAnalyzer::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void WeightAnalyzer::persistentOutput(PersistentOStream &) const {}
void WeightAnalyzer::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<WeightAnalyzer,AnalysisHandler>
describeHerwigWeightAnalyzer("Herwig::WeightAnalyzer", "Herwig.so");
void WeightAnalyzer::Init() {
static ClassDocumentation<WeightAnalyzer> documentation
("There is no documentation for the WeightAnalyzer class");
static Switch<WeightAnalyzer,bool> interfacekeepinputtopmass
("Gnuplot output",
"Switch On/Off gnuplot",
&WeightAnalyzer::gnuplot, true, false, false);
static SwitchOption interfacekeepinputtopmassYes
(interfacekeepinputtopmass,
"Yes",
"Yes",
true);
static SwitchOption interfacekeepinputtopmassNo
(interfacekeepinputtopmass,
"No",
"No",
false);
}
diff --git a/MatrixElement/Matchbox/Tests/WeightAnalyzer.h b/MatrixElement/Matchbox/Tests/WeightAnalyzer.h
--- a/MatrixElement/Matchbox/Tests/WeightAnalyzer.h
+++ b/MatrixElement/Matchbox/Tests/WeightAnalyzer.h
@@ -1,216 +1,208 @@
// -*- C++ -*-
#ifndef Herwig_WeightAnalyzer_H
#define Herwig_WeightAnalyzer_H
//
// This is the declaration of the WeightAnalyzer class.
//
#include "ThePEG/Handlers/AnalysisHandler.h"
namespace Herwig {
using namespace ThePEG;
/**
* Here is the documentation of the WeightAnalyzer class.
*
* @see \ref WeightAnalyzerInterfaces "The interfaces"
* defined for WeightAnalyzer.
*/
class WeightAnalyzer: public AnalysisHandler {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
WeightAnalyzer();
- /**
- * The destructor.
- */
- virtual ~WeightAnalyzer();
- //@}
-
public:
/** @name Virtual functions required by the AnalysisHandler class. */
//@{
/**
* Analyze a given Event. Note that a fully generated event
* may be presented several times, if it has been manipulated in
* between. The default version of this function will call transform
* to make a lorentz transformation of the whole event, then extract
* all final state particles and call analyze(tPVector) of this
* analysis object and those of all associated analysis objects. The
* default version will not, however, do anything on events which
* have not been fully generated, or have been manipulated in any
* way.
* @param event pointer to the Event to be analyzed.
* @param ieve the event number.
* @param loop the number of times this event has been presented.
* If negative the event is now fully generated.
* @param state a number different from zero if the event has been
* manipulated in some way since it was last presented.
*/
virtual void analyze(tEventPtr event, long ieve, int loop, int state);
//@}
protected:
/**
* 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();
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 sum of weights
*/
double sumWeights;
/**
* The sum of positive weights
*/
double sumPositiveWeights;
/**
* The sum of negative weights
*/
double sumNegativeWeights;
/**
* The sum of weights calculated by subprocess group weights
*/
double sumGroupWeights;
/**
* The sum of positive weights calculated by subprocess group weights
*/
double sumPositiveGroupWeights;
/**
* The sum of negative weights calculated by subprocess group weights
*/
double sumNegativeGroupWeights;
/**
* The maximum deviation of the group weight sum from one
*/
double maxDeviationGroupWeight;
/**
* The maximum deviation of the event weight sum from the overall
* event weight
*/
double maxDeviationEventWeight;
/**
* Total number of positive weights
*/
double nPositiveWeights;
/**
* Total number of negative weights
*/
double nNegativeWeights;
/**
* The maximum postive weight
*/
double maxPositiveWeight;
/**
* The maximum absolute negative weight
*/
double maxNegativeWeight;
/**
* Histogram of positive weight occurences
*/
map<double,double> positiveWeightDistribution;
/**
* Histogram of negative weight occurences
*/
map<double,double> negativeWeightDistribution;
/**
* Gnuplot output
*/
bool gnuplot;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
WeightAnalyzer & operator=(const WeightAnalyzer &) = delete;
};
}
#endif /* Herwig_WeightAnalyzer_H */
diff --git a/MatrixElement/Matchbox/Utility/DensityOperator.cc b/MatrixElement/Matchbox/Utility/DensityOperator.cc
--- a/MatrixElement/Matchbox/Utility/DensityOperator.cc
+++ b/MatrixElement/Matchbox/Utility/DensityOperator.cc
@@ -1,479 +1,477 @@
// -*- C++ -*-
//
// DensityOperator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 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 DensityOperator class.
//
#include "DensityOperator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXCombData.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
DensityOperator::DensityOperator() : Nc(3.0), TR(0.5) { }
-DensityOperator::~DensityOperator() {}
-
void DensityOperator::clear() {
theCorrelatorMap.clear();
}
// Prepare density operator if not done before
void DensityOperator::prepare(const cPDVector& mePartonData) {
// Take parton data and create key of type 33bar888 to use as key for basis
vector<PDT::Colour> mePartonDataColoured = theColourBasis->normalOrderMap(mePartonData);
if( theDensityOperatorMap.count( mePartonDataColoured ) == 0 ){
// Get basis dimension
size_t dim = theColourBasis->prepare( mePartonData, false );
// Allocate space for density matrix
theDensityOperatorMap.insert(make_pair(mePartonDataColoured,matrix<Complex> (dim,dim)));
}
}
// Fill the density matrix for the first time
void DensityOperator::fill(const Ptr<MatchboxXComb>::ptr MBXCombPtr,
const cPDVector& partons,
const vector<Lorentz5Momentum>& momenta){
// Map from helicity structure to amplitude vector in the color basis
const map<vector<int>,CVector>& amplitudeMap = MBXCombPtr->lastAmplitudes();
const cPDVector& mePartonData = MBXCombPtr->mePartonData();
// Get the dimension of the basis for the indexChange method
size_t dim = theColourBasis->prepare(mePartonData,false);
// Normal order partons according to ColourBasis
const vector<PDT::Colour> mePartonDataColoured = theColourBasis->normalOrderMap(mePartonData);
// Get the colour basis to colour basis map for this hard subprocess
map<cPDVector,map<size_t,size_t> >::iterator cb2cbit = theColourBasisToColourBasisMap.find(mePartonData);
// Fill the map with this hard subprocess if it doesn't have it yet
if ( cb2cbit == theColourBasisToColourBasisMap.end() ) {
// Get the index map for the partons as they are ordered in the MatchboxXComb
// object
const map<size_t,size_t>& mbIndexMap = theColourBasis->indexMap().at(mePartonData);
// Get the index map for the partons as they are ordered
// in the shower.
// Use prepare, as it might not have been done for this order of the partons
theColourBasis->prepare(partons,false);
const map<size_t,size_t>& showerIndexMap = theColourBasis->indexMap().at(partons);
// ensure the maps are of the same size
assert( mbIndexMap.size() == showerIndexMap.size() );
// Loop over both sets of partons to determine how the order between them
// differs, then translate the index to the colour basis and put the
// key-value pair into the map
map<size_t,size_t> cb2cbMap;
// Get the momenta for comparison
const vector<Lorentz5Momentum>& meMomenta = MBXCombPtr->matchboxME()->lastMEMomenta();
// Make sure there's the same number of momenta in both vectors
assert( momenta.size() == meMomenta.size() );
bool done;
// Boost the momenta to the same frame
const vector<Lorentz5Momentum> momentaCM = boostToRestFrame(momenta);
for ( size_t i = 0; i < momentaCM.size(); i++ ) {
// The cb2cb map is intended to translate how the indices
// are different in the colour basis due to the different
// orderings of the partons, so it should only bother
// with coloured particles.
if ( partons[i]->coloured() ) {
done = false;
for ( size_t j = 0; j < meMomenta.size(); j++ ) {
if ( !done ) {
if ( compareMomentum(momentaCM[i],meMomenta[j]) ) {
cb2cbMap[mbIndexMap.at(i)] = showerIndexMap.at(j);
done = true;
}
}
}
}
}
// Make sure all momenta have been identified
assert( cb2cbMap.size() == mePartonDataColoured.size() );
// Add the map to the cache
theColourBasisToColourBasisMap[mePartonData] = cb2cbMap;
// Get the iterator
cb2cbit = theColourBasisToColourBasisMap.find(mePartonData);
}
// With the cb2cb index map we can create the basis vector index map
const map<size_t,size_t> vectorMap = theColourBasis->indexChange(mePartonDataColoured,
dim,cb2cbit->second);
// Prepare density operator (allocate) for set of particles
prepare(mePartonData);
// Check that density operator (place holder for) exist in density operator map
map<vector<PDT::Colour>,matrix<Complex> >::iterator dOit = theDensityOperatorMap.find(mePartonDataColoured);
assert(dOit != theDensityOperatorMap.end());
// Initialize the density operator
matrix<Complex>& densOp = dOit->second;
for(unsigned int i = 0; i < (amplitudeMap.begin()->second).size(); i++){
for(unsigned int j = 0; j < (amplitudeMap.begin()->second).size(); j++){
densOp (i,j) = 0;
}
}
// Fill the density operator, ok to sum over helicities since the density operator
// exist at the probability level
CVector amplitude;
for ( map<vector<int>,CVector>::const_iterator itHel = amplitudeMap.begin();
itHel != amplitudeMap.end(); itHel++ ) {
amplitude = itHel->second;
for ( unsigned int i = 0; i < amplitude.size(); i++ ) {
for ( unsigned int j = 0; j < amplitude.size(); j++ ) {
// vectorMap is used such that densOp is filled according to the
// basis order defined by the input cPDVector partons.
densOp (vectorMap.at(i),vectorMap.at(j)) += amplitude(i)*std::conj(amplitude(j));
}
}
}
// Colour conservation check
colourConservation(mePartonData);
}
// Update density matrix after emitting or splitting a gluon
// The emissionsMap argument contains the relation of the indices in the smaller (before)
// and larger basis (after). the first 3-tuple contains the indices
// (emitter before, emitter after, emitted parton)
// The map contains the old and new indices of all other partons (not involved)
void DensityOperator::evolve(const map<pair<size_t,size_t>,Complex>& Vijk,
const cPDVector& before,
const cPDVector& after,
const map<std::tuple<size_t,size_t,size_t>,map<size_t,size_t> >& emissionsMap,
const bool splitAGluon,
const bool initialGluonSplitting) {
size_t dimBefore = theColourBasis->prepare( before, false );
size_t dimAfter = theColourBasis->prepare( after, false );
vector<PDT::Colour> beforeColoured = theColourBasis->normalOrderMap(before);
vector<PDT::Colour> afterColoured = theColourBasis->normalOrderMap(after);
const map<vector<PDT::Colour>,matrix<Complex> >::iterator dOit = theDensityOperatorMap.find(beforeColoured);
assert(dOit != theDensityOperatorMap.end());
const matrix<Complex>& densOpBefore = dOit->second;
prepare(after);
matrix<Complex>& densOpAfter = theDensityOperatorMap[afterColoured];
for(size_t i = 0; i < densOpAfter.size1(); i++){
for(size_t j = 0; j < densOpAfter.size2(); j++){
densOpAfter(i,j) = 0;
}
}
compressed_matrix<double> Tij;
matrix<Complex> TijMn (dimAfter,dimBefore);
compressed_matrix<double> Tk;
matrix<Complex> TijMnTkdagger (dimAfter,dimAfter);
Complex V;
// Compensate for sign from updated density matrix
// TODO Check signs again
double sign = -1.0;
if ( splitAGluon )
sign = 1.0;
// Loop over emitter legs ij and recoil legs k and add the contribution,
// for Vijk is assumed to contain the factor 4*pi*\alpha_s/pi.pj
typedef map<std::tuple<size_t,size_t,size_t>,map<size_t,size_t> > dictMap;
int ij,k;
// Loop over emitters
for(dictMap::const_iterator ijit = emissionsMap.begin();
ijit != emissionsMap.end(); ijit++) {
// get first element in 3-tuple, i.e., emitter before
ij = std::get<0>(ijit->first);
assert(before[ij]->coloured());
// Get rectangular matrices T_{ij} or S_{ij} taking us from the
// smaller to the larger basis depending on
// the involved particles before and after, the emitter index before ij,
// the emitter after and the emitted parton index
int i=std::get<1>(ijit->first); // emitter after
int j=std::get<2>(ijit->first);// emitted parton
Tij = theColourBasis->charge(before,after,
ij,i,j,ijit->second).first;
TijMn = prodSparseDense(Tij,densOpBefore);
// Loop over spectators
for(dictMap::const_iterator kit = emissionsMap.begin();
kit != emissionsMap.end(); kit++) {
k = std::get<0>(kit->first);
assert(before[k]->coloured());
// Standard case of gluon radiation
if ( ijit != kit || splitAGluon || initialGluonSplitting ) {
int k_after=std::get<1>(kit->first); // For color structure k now has role of emitter
int k_emission= std::get<2>(kit->first); // Emitted parton index
Tk = theColourBasis->charge(before,after,
k, k_after, k_emission, kit->second).first;
TijMnTkdagger = prodDenseSparse(TijMn,Tk);
// sign == -1.0 if it isn't a gluon splitting into a qqbar pair
V = sign*(1.0/colourNorm(before[ij]))*
Vijk.at(make_pair(ij,k));
densOpAfter += V*TijMnTkdagger;
}
}
}
// Check that the density operator does not vanish
assert( theColourBasis->me2(after,densOpAfter) != 0.0 );
colourConservation(after);
}
// The 3-tuple contains (emitter index, spectator index, emission pid)
double DensityOperator::colourMatrixElementCorrection(const std::tuple<size_t,size_t,long>& ikemission,
const cPDVector& particles) {
const int i = std::get<0>(ikemission);
const int k = std::get<1>(ikemission);
//const long emissionID = std::get<2>(ikemission);
// Get the density operator
// normal order particles as in ColourBasis
vector<PDT::Colour> particlesColoured = theColourBasis->normalOrderMap(particles);
// ... and find corresponding density operator
const map<vector<PDT::Colour>,matrix<Complex> >::iterator particlesit = theDensityOperatorMap.find(particlesColoured);
assert(particlesit != theDensityOperatorMap.end());
const matrix<Complex>& densOp = particlesit->second;
double Ti2 = colourNorm(particles[i]);
// Emitter-spectator pair
const pair<size_t,size_t> ik = make_pair(i,k);
// Create key for color matrix element correction map
pair<vector<PDT::Colour>,pair<size_t,size_t> > particlesAndLegs = make_pair(particlesColoured,ik);
// Result
double res = 0;
// Check if it has already been calculated
// TODO: move this check earlier (we only need particlesColoured to check if it has been
// calculated).
// Check for color matrix element associated with key, and calculate if not done
const map<pair<vector<PDT::Colour>,pair<size_t,size_t> >,double >::const_iterator corrit = theCorrelatorMap.find(particlesAndLegs);
if ( corrit == theCorrelatorMap.end() ) {
double corrME2 = theColourBasis->colourCorrelatedME2(ik,particles,densOp);
double me2 = theColourBasis->me2(particles,densOp);
res = -(1/Ti2)*corrME2/me2;
if ( particles[i]->id() == ParticleID::g )
res *= 2.;
theCorrelatorMap.insert(make_pair(particlesAndLegs,res));
} else {
res = corrit->second;
}
return res;
}
double DensityOperator::colourNorm(const cPDPtr particle) {
if ( particle->id() == ParticleID::g ) {
return Nc; //is 3.0 for Nc = 3, TR = 1/2
} else if ( particle->iColour() == PDT::Colour3 || particle->iColour() == PDT::Colour3bar ) {
return TR*(Nc*Nc-1.)/Nc; // is 4.0/3.0 for Nc = 3, TR = 1/2
} else {
throw Exception() << "Colour matrix element corrections only work "
<< "on quark and gluon legs. "
<< Exception::runerror;
}
}
void DensityOperator::colourConservation(const cPDVector& particles) {
// To contain (emitter, spectator, emission pid)
std::tuple<size_t,size_t,long> ikemission;
// Normal order particles as defined in ColourBasis
const vector<PDT::Colour> particlesColoured = theColourBasis->normalOrderMap(particles);
vector<double> sum(particlesColoured.size(),0.0);
size_t iterm = 0;
// To compensate for the CMEC having a 1/(1+\delta(i is gluon)) factor
// in the splitting kernel
double gluonFactor = 1.0;
// Loop over "emitters" to check color conservation for
for ( size_t i = 0; i < particles.size(); i++ ) {
if ( particles[i]->coloured() ) {
for ( size_t k = 0; k < particles.size(); k++ ) {
if ( particles[k]->coloured() && i != k ) {
ikemission = std::make_tuple(i,k,ParticleID::g);
if ( particles[i]->id() != ParticleID::g ) {
gluonFactor = 1.0;
} else {
gluonFactor = 1./2.;
}
sum[iterm] += gluonFactor*colourMatrixElementCorrection(ikemission,particles);
}
}
iterm++;
}
}
for ( size_t i = 0; i < sum.size(); i++ )
assert( std::abs(sum[i]-1.0) < pow(10.0,-10.0));
}
matrix<Complex> DensityOperator::prodSparseDense(const compressed_matrix<double>& Tij,
const matrix<Complex>& Mn){
// Dimension before emission
size_t dimBefore = Tij.size2();
// Dimension after emission
size_t dimAfter = Tij.size1();
//Check matrix dimensions
assert( dimBefore == Mn.size1() );
// Allocate memory for the matrix
matrix<Complex> TijMn (dimAfter,dimBefore,0);
// Use iterators for the compressed matrix to iterate only over the non-zero
// elements.
size_t ii;
size_t jj;
for ( compressed_matrix<double>::const_iterator1 it1 = Tij.begin1();
it1 != Tij.end1(); it1++ ) {
for ( compressed_matrix<double>::const_iterator2 it2 = it1.begin();
it2 != it1.end(); it2++ ) {
ii = it2.index1();
jj = it2.index2();
for ( size_t kk = 0; kk < dimBefore; kk++ ) {
// *it2 is Tij(ii,jj)
TijMn(ii,kk) += (*it2)*Mn(jj,kk);
}
}
}
return TijMn;
}
matrix<Complex> DensityOperator::prodDenseSparse(const matrix<Complex>& TijMn,
const compressed_matrix<double>& Tk){
// The compressed matrix comes from the charge method, do not transpose yet
// Dimension after emission
size_t dimAfter = Tk.size1();//Since this method returns TijMn*Tk^\dagger
//Check matrix dimensions
assert( TijMn.size2() == Tk.size2() );
// Allocate memory for the matrix
matrix<Complex> TijMnTkdagger (dimAfter,dimAfter,0);
size_t jj;
size_t kk;
for ( compressed_matrix<double>::const_iterator1 it1 = Tk.begin1();
it1 != Tk.end1(); it1++ ) {
for ( compressed_matrix<double>::const_iterator2 it2 = it1.begin();
it2 != it1.end(); it2++ ) {
jj = it2.index2();//transposing Tk jj is index2(), not index1()
kk = it2.index1();//transposing Tk
for ( size_t ii = 0; ii < dimAfter; ii++ ) {
// *it2 is Tk(kk,jj) = trans(Tk)(jj,kk)
TijMnTkdagger(ii,kk) += TijMn(ii,jj)*(*it2);
}
}
}
return TijMnTkdagger;
}
vector<Lorentz5Momentum> DensityOperator::boostToRestFrame(const vector<Lorentz5Momentum>& momenta) {
// We need 2 initial particles
assert(momenta.size() >= 2);
// The boosted vectors
vector<Lorentz5Momentum> vboosted = momenta;
// The boost should be to the rest frame of the initial particles
Boost b = (momenta[0] + momenta[1]).findBoostToCM();
// Boost all of the vectors
for ( size_t i = 0; i < momenta.size(); i++ ) {
vboosted[i].boost(b);
}
return vboosted;
}
bool DensityOperator::compareMomentum(const Lorentz5Momentum& p, const Lorentz5Momentum& q) {
bool equal = true;
// Compares two momentum vectors p and q, if they are close enough (defined by the
// double eps below) it returns true. This is sufficient to distinguish particles
// in the matrix element as we are not interested in the matrix element for extremely
// collinear radiation (better described by the parton shower).
// Create the difference of the two vectors
const Lorentz5Momentum l = p - q;
// A relevant size that is guaranteed to be larger than 0
const Energy2 e2 = p.t()*p.t();
// Size of the difference that would be considered equal
const double eps = pow(10.,-15.);
if ( l.x()*l.x()/e2 > eps )
equal = false;
if ( l.y()*l.y()/e2 > eps )
equal = false;
if ( l.z()*l.z()/e2 > eps )
equal = false;
if ( l.t()*l.t()/e2 > eps )
equal = false;
return equal;
}
IBPtr DensityOperator::clone() const {
return new_ptr(*this);
}
IBPtr DensityOperator::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DensityOperator::persistentOutput(PersistentOStream &) const {
// *** ATTENTION *** os << ; // Add all member variable which should be written persistently here.
}
void DensityOperator::persistentInput(PersistentIStream &, int) {
// *** ATTENTION *** is >> ; // Add all member variable which should be read persistently here.
}
// *** 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<DensityOperator,HandlerBase>
describeHerwigDensityOperator("Herwig::DensityOperator", "DensityOperator.so");
void DensityOperator::Init() {
static ClassDocumentation<DensityOperator> documentation
("There is no documentation for the DensityOperator class");
}
diff --git a/MatrixElement/Matchbox/Utility/DensityOperator.h b/MatrixElement/Matchbox/Utility/DensityOperator.h
--- a/MatrixElement/Matchbox/Utility/DensityOperator.h
+++ b/MatrixElement/Matchbox/Utility/DensityOperator.h
@@ -1,248 +1,240 @@
// -*- C++ -*-
//
// DensityOperator.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 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_DensityOperator_H
#define Herwig_DensityOperator_H
//
// This is the declaration of the DensityOperator class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "Herwig/MatrixElement/Matchbox/Utility/ColourBasis.h"
#include <tuple>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/vector.hpp>
namespace Herwig {
using namespace ThePEG;
typedef boost::numeric::ublas::vector<Complex> CVector;
/**
* Here is the documentation of the DensityOperator class.
*
* @see \ref DensityOperatorInterfaces "The interfaces"
* defined for DensityOperator.
*/
class DensityOperator: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
DensityOperator();
- /**
- * The destructor.
- */
- virtual ~DensityOperator();
- //@}
-
public:
/**
* Clears theDensityOperatorMap.
*/
void clear();
/**
* Prepare for the given sub process.
*/
void prepare(const cPDVector&);
/**
* Fill the density operator for the given hard subprocess, summing over all
* helicity configurations.
*/
void fill(const Ptr<MatchboxXComb>::ptr,
const cPDVector&, const vector<Lorentz5Momentum>& momenta);
/**
* Evolve the density operator, by
* M_{n+1} = -\sum_{i,k}{-4*pi*alpha_s/Ti2*V_{ij,k} T_{i,n}M_nT_{k,n}^\dag},
* see arXiv:1206.0180 eq. (5), note that the pi*pj factor is assumed to be
* included in V_{ij,k}.
*/
void evolve(const map<pair<size_t,size_t>,Complex>& Vijk,
const cPDVector& before,
const cPDVector& after,
const map<std::tuple<size_t,size_t,size_t>,map<size_t,size_t> >& emissionsMap,
const bool splitAGluon,
const bool initialGluonSplitting);
/**
* Calculate the colour matrix element correction.
* -(1+delta(i,gluon))/Ti^2 Tr(Sn+1 Ti Mn Tk^dagger)/Tr(Sn Mn)
* where the bracket in front compensates for the gluon symmetry factor,
* Ti^2 is C_f or C_a, Sn+1 is the matrix of scalar products, and
* Ti is the radiation matrix.
* The first arg contains (emitter index, spectator index, emission pid)
*
*/
double colourMatrixElementCorrection(const std::tuple<size_t,size_t,long>& ikemission,
const cPDVector& particles);
/**
* Checking colour conservation for the colour matrix element corrections.
*/
void colourConservation(const cPDVector& particles);
/**
* Get the colour basis.
*/
Ptr<ColourBasis>::tptr colourBasis() { return theColourBasis; }
/**
* Get the colour basis.
*/
const Ptr<ColourBasis>::tptr colourBasis() const { return theColourBasis; }
/**
* Set the colour basis.
*/
void colourBasis(Ptr<ColourBasis>::ptr ptr) { theColourBasis = ptr; }
/**
* Get the correlator map.
*/
const map<pair<vector<PDT::Colour>,pair<size_t,size_t> >,double>& correlatorMap() const {
return theCorrelatorMap;
}
/** @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:
/**
* Number of colours used in colourNorm.
*/
double Nc;
/**
* QCD vertex normalization.
*/
double TR;
/**
* Normalization of colour charges \mathbf{T}_{ij}^2.
*/
double colourNorm(const cPDPtr particle);
/**
* Fast evaluation of Tij*Mn, where a Tij is the matrix from ColourBasis::charge,
* which is a sparse matrix, and Mn is the density operator, a dense matrix.
*
*/
matrix<Complex> prodSparseDense(const compressed_matrix<double>&,
const matrix<Complex>&);
/**
* Fast evaluation of TijMn*Tkdagger, where a TijMn is the result from the method
* prodSparseDense, a dense matrix, and Tkdagger is the transponse conjugate of
* the matrix from ColourBasis::charge, a sparse matrix.
*
*/
matrix<Complex> prodDenseSparse(const matrix<Complex>&,
const compressed_matrix<double>&);
/**
* Boosts a vector of momenta to the rest frame of the initial pair
* of particles (the first 2 elements of the argument vector). Returns
* the boosted vectors
*/
vector<Lorentz5Momentum> boostToRestFrame(const vector<Lorentz5Momentum>& momenta);
/**
* Boosts a vector of momenta to the rest frame of the initial pair
*/
bool compareMomentum(const Lorentz5Momentum& p, const Lorentz5Momentum& q);
/**
* Mapping of colour structures to density operator matrices.
*
*/
map<vector<PDT::Colour>,matrix<Complex> > theDensityOperatorMap;
/**
* Mapping of colour structures and legs to colour correlators.
*/
map<pair<vector<PDT::Colour>,pair<size_t,size_t> >,double> theCorrelatorMap;
/**
* A map from the hard subprocess particles to a map of amplitude colour
* basis order to the normal ordered colour basis.
*/
map<cPDVector, map<size_t,size_t> > theColourBasisToColourBasisMap;
/**
* Colour basis used.
*/
Ptr<ColourBasis>::ptr theColourBasis;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DensityOperator & operator=(const DensityOperator &) = delete;
};
}
#endif /* Herwig_DensityOperator_H */
diff --git a/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.cc b/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.cc
--- a/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.cc
+++ b/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.cc
@@ -1,102 +1,100 @@
// -*- C++ -*-
//
// MatchboxFactoryMatcher.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the MatchboxFactoryMatcher class.
//
#include "MatchboxFactoryMatcher.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxFactoryMatcher::MatchboxFactoryMatcher()
: theGroup("") {}
-MatchboxFactoryMatcher::~MatchboxFactoryMatcher() {}
-
IBPtr MatchboxFactoryMatcher::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxFactoryMatcher::fullclone() const {
return new_ptr(*this);
}
PMPtr MatchboxFactoryMatcher::pmclone() const {
return new_ptr(*this);
}
bool MatchboxFactoryMatcher::check(const ParticleData & data) const {
return theIds.find(data.id()) != theIds.end();
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxFactoryMatcher::persistentOutput(PersistentOStream & os) const {
os << theGroup << theIds;
}
void MatchboxFactoryMatcher::persistentInput(PersistentIStream & is, int) {
is >> theGroup >> theIds;
}
void MatchboxFactoryMatcher::doinit() {
if ( !MatchboxFactory::isMatchboxRun() )
return;
if ( !MatchboxFactory::currentFactory() )
throw Exception()
<< "MatchboxFactoryMatcher::doinit(): No factory object is available in the matcher '"
<< name() << "'" << Exception::runerror;
map<string,PDVector>::const_iterator grp
= MatchboxFactory::currentFactory()->particleGroups().find(theGroup);
if ( grp == MatchboxFactory::currentFactory()->particleGroups().end() )
throw Exception()
<< "MatchboxFactoryMatcher::doinit(): Particle group '" << theGroup << "' not defined in factory object '"
<< MatchboxFactory::currentFactory()->name() << "'" << Exception::runerror;
theIds.clear();
for ( PDVector::const_iterator p = grp->second.begin();
p != grp->second.end(); ++p )
theIds.insert((**p).id());
MatcherBase::doinit();
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxFactoryMatcher,ThePEG::MatcherBase>
describeHerwigMatchboxFactoryMatcher("Herwig::MatchboxFactoryMatcher", "Herwig.so");
void MatchboxFactoryMatcher::Init() {
static ClassDocumentation<MatchboxFactoryMatcher> documentation
("MatchboxFactoryMatcher matches particles according to MatchboxFactory particle groups");
static Parameter<MatchboxFactoryMatcher,string> interfaceGroup
("Group",
"Set the group name to match.",
&MatchboxFactoryMatcher::theGroup, "",
false, false);
}
diff --git a/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.h b/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.h
--- a/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.h
+++ b/MatrixElement/Matchbox/Utility/MatchboxFactoryMatcher.h
@@ -1,147 +1,139 @@
// -*- C++ -*-
//
// MatchboxFactoryMatcher.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxFactoryMatcher_H
#define Herwig_MatchboxFactoryMatcher_H
//
// This is the declaration of the MatchboxFactoryMatcher class.
//
#include "ThePEG/PDT/MatcherBase.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxFactoryMatcher matches particles according to
* MatchboxFatory particle groups
*
* @see \ref MatchboxFactoryMatcherInterfaces "The interfaces"
* defined for MatchboxFactoryMatcher.
*/
class MatchboxFactoryMatcher: public ThePEG::MatcherBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxFactoryMatcher();
- /**
- * The destructor.
- */
- virtual ~MatchboxFactoryMatcher();
- //@}
-
public:
/**
* Check if a particle type meets the criteria.
*/
virtual bool check(const ParticleData &) const;
/**
* Specialized clone method for MatcherBase used by the
* Repository. A sub class must make sure that also the MatcherBase
* object corresponding to the complex conjugate of this is cloned.
*/
virtual PMPtr pmclone() 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).
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object after the setup phase before saving an
* EventGenerator to disk.
* @throws InitException if object could not be initialized properly.
*/
virtual void doinit();
//@}
private:
/**
* The particle group to be matched
*/
string theGroup;
/**
* The set of particle ids to be matched
*/
set<long> theIds;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxFactoryMatcher & operator=(const MatchboxFactoryMatcher &) = delete;
};
}
#endif /* Herwig_MatchboxFactoryMatcher_H */
diff --git a/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.cc b/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.cc
--- a/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.cc
+++ b/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.cc
@@ -1,83 +1,81 @@
// -*- C++ -*-
//
// MatchboxScaleChoice.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxScaleChoice class.
//
#include "MatchboxScaleChoice.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
MatchboxScaleChoice::MatchboxScaleChoice()
: theFixedScale(ZERO), theFixedQEDScale(ZERO) {}
-MatchboxScaleChoice::~MatchboxScaleChoice() {}
-
IBPtr MatchboxScaleChoice::clone() const {
return new_ptr(*this);
}
IBPtr MatchboxScaleChoice::fullclone() const {
return new_ptr(*this);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void MatchboxScaleChoice::persistentOutput(PersistentOStream & os) const {
os << theLastXComb << ounit(theFixedScale,GeV) << ounit(theFixedQEDScale,GeV);
}
void MatchboxScaleChoice::persistentInput(PersistentIStream & is, int) {
is >> theLastXComb >> iunit(theFixedScale,GeV) >> iunit(theFixedQEDScale,GeV);
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MatchboxScaleChoice,HandlerBase>
describeHerwigMatchboxScaleChoice("Herwig::MatchboxScaleChoice", "Herwig.so");
void MatchboxScaleChoice::Init() {
static ClassDocumentation<MatchboxScaleChoice> documentation
("MatchboxScaleChoice is the base class for scale choices "
"within Matchbox.");
static Parameter<MatchboxScaleChoice,Energy> interfaceFixedScale
("FixedScale",
"Set a fixed scale.",
&MatchboxScaleChoice::theFixedScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<MatchboxScaleChoice,Energy> interfaceFixedQEDScale
("FixedQEDScale",
"Set a fixed QED scale.",
&MatchboxScaleChoice::theFixedQEDScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
}
diff --git a/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h b/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h
--- a/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h
+++ b/MatrixElement/Matchbox/Utility/MatchboxScaleChoice.h
@@ -1,169 +1,161 @@
// -*- C++ -*-
//
// MatchboxScaleChoice.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxScaleChoice_H
#define Herwig_MatchboxScaleChoice_H
//
// This is the declaration of the MatchboxScaleChoice class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/Handlers/LastXCombInfo.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief MatchboxScaleChoice is the base class for scale choices
* within Matchbox.
*
*/
class MatchboxScaleChoice: public HandlerBase, public LastXCombInfo<StandardXComb> {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MatchboxScaleChoice();
- /**
- * The destructor.
- */
- virtual ~MatchboxScaleChoice();
- //@}
-
public:
/**
* Clone this scale choice.
*/
Ptr<MatchboxScaleChoice>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<MatchboxScaleChoice>::ptr>(clone());
}
/**
* Set the XComb object.
*/
virtual void setXComb(tStdXCombPtr xc) {
theLastXComb = xc;
}
/**
* Return the renormalization scale. This default version returns
* shat.
*/
virtual Energy2 renormalizationScale() const {
return theFixedScale == ZERO ? lastSHat() : sqr(theFixedScale);
}
/**
* Return the factorization scale. This default version returns
* shat.
*/
virtual Energy2 factorizationScale() const {
return theFixedScale == ZERO ? lastSHat() : sqr(theFixedScale);
}
/**
* Return the QED renormalization scale. This default version returns
* the Z mass squared.
*/
virtual Energy2 renormalizationScaleQED() const {
if ( theFixedQEDScale != ZERO )
return sqr(theFixedQEDScale);
Energy mZ = getParticleData(ParticleID::Z0)->hardProcessMass();
return mZ*mZ;
}
/**
* Return the shower hard scale. This default implementation returns the
* factorization scale.
*/
virtual Energy2 showerScale() const {
return factorizationScale();
}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* A fixed scale choice. If zero, shat will be used.
*/
Energy theFixedScale;
/**
* A fixed QED scale choice. If zero, shat will be used.
*/
Energy theFixedQEDScale;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxScaleChoice & operator=(const MatchboxScaleChoice &) = delete;
};
}
#endif /* Herwig_MatchboxScaleChoice_H */
diff --git a/MatrixElement/Matchbox/Utility/MatchboxXComb.cc b/MatrixElement/Matchbox/Utility/MatchboxXComb.cc
--- a/MatrixElement/Matchbox/Utility/MatchboxXComb.cc
+++ b/MatrixElement/Matchbox/Utility/MatchboxXComb.cc
@@ -1,78 +1,76 @@
// -*- C++ -*-
//
// MatchboxXComb.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxXComb class.
//
#include "MatchboxXComb.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
using namespace Herwig;
MatchboxXComb::MatchboxXComb()
: StandardXComb() {
flushCaches();
}
-MatchboxXComb::~MatchboxXComb() {}
-
MatchboxXComb::MatchboxXComb(Energy newMaxEnergy, const cPDPair & inc,
tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
tPExtrPtr newExtractor, tCascHdlPtr newCKKW,
const PBPair & newPartonBins, tCutsPtr newCuts, tMEPtr newME,
const DiagramVector & newDiagrams, bool mir,
tStdXCombPtr newHead)
: StandardXComb(newMaxEnergy, inc,
newEventHandler,newSubProcessHandler,
newExtractor, newCKKW,
newPartonBins, newCuts, newME,
newDiagrams, mir,
newHead),
MatchboxXCombData(newME) {
flushCaches();
}
MatchboxXComb::MatchboxXComb(tStdXCombPtr newHead,
const PBPair & newPartonBins, tMEPtr newME,
const DiagramVector & newDiagrams)
: StandardXComb(newHead, newPartonBins, newME, newDiagrams),
MatchboxXCombData(newME) {
flushCaches();
}
void MatchboxXComb::clean() {
StandardXComb::clean();
flushCaches();
}
void MatchboxXComb::persistentOutput(PersistentOStream & os) const {
MatchboxXCombData::persistentOutput(os);
}
void MatchboxXComb::persistentInput(PersistentIStream & is, int version) {
MatchboxXCombData::persistentInput(is,version);
}
// *** 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<MatchboxXComb,StandardXComb>
describeHerwigMatchboxXComb("Herwig::MatchboxXComb", "Herwig.so");
void MatchboxXComb::Init() {
static ClassDocumentation<MatchboxXComb> documentation
("MatchboxXComb extents StandardXComb.");
}
diff --git a/MatrixElement/Matchbox/Utility/MatchboxXComb.h b/MatrixElement/Matchbox/Utility/MatchboxXComb.h
--- a/MatrixElement/Matchbox/Utility/MatchboxXComb.h
+++ b/MatrixElement/Matchbox/Utility/MatchboxXComb.h
@@ -1,108 +1,102 @@
// -*- C++ -*-
//
// MatchboxXComb.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxXComb_H
#define Herwig_MatchboxXComb_H
//
// This is the declaration of the MatchboxXComb class.
//
#include "ThePEG/Handlers/StandardXComb.h"
#include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXCombData.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief Matchbox extensions to StandardXComb
*/
class MatchboxXComb: public StandardXComb, public MatchboxXCombData {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* Standard constructor.
*/
MatchboxXComb(Energy newMaxEnergy, const cPDPair & inc,
tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
tPExtrPtr newExtractor, tCascHdlPtr newCKKW,
const PBPair & newPartonBins, tCutsPtr newCuts, tMEPtr newME,
const DiagramVector & newDiagrams, bool mir,
tStdXCombPtr newHead = tStdXCombPtr());
/**
* Constructor given a head xcomb.
*/
MatchboxXComb(tStdXCombPtr newHead,
const PBPair & newPartonBins, tMEPtr newME,
const DiagramVector & newDiagrams);
/**
* Default constructor.
*/
MatchboxXComb();
-
- /**
- * Destructor.
- */
- virtual ~MatchboxXComb();
-
//@}
public:
/**
* Reset all saved data about last generated phasespace point;
*/
virtual void clean();
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();
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxXComb & operator=(const MatchboxXComb &) = delete;
};
}
#endif /* Herwig_MatchboxXComb_H */
diff --git a/MatrixElement/Matchbox/Utility/MatchboxXCombGroup.cc b/MatrixElement/Matchbox/Utility/MatchboxXCombGroup.cc
--- a/MatrixElement/Matchbox/Utility/MatchboxXCombGroup.cc
+++ b/MatrixElement/Matchbox/Utility/MatchboxXCombGroup.cc
@@ -1,70 +1,68 @@
// -*- C++ -*-
//
// MatchboxXCombGroup.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MatchboxXCombGroup class.
//
#include "MatchboxXCombGroup.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
using namespace Herwig;
MatchboxXCombGroup::MatchboxXCombGroup()
: StdXCombGroup() {
flushCaches();
}
-MatchboxXCombGroup::~MatchboxXCombGroup() {}
-
MatchboxXCombGroup::MatchboxXCombGroup(Energy newMaxEnergy, const cPDPair & inc,
tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
tPExtrPtr newExtractor, tCascHdlPtr newCKKW,
const PBPair & newPartonBins, tCutsPtr newCuts, tMEGroupPtr newME,
const DiagramVector & newDiagrams, bool mir,
tStdXCombPtr newHead)
: StdXCombGroup(newMaxEnergy, inc,
newEventHandler, newSubProcessHandler,
newExtractor, newCKKW,
newPartonBins, newCuts, newME,
newDiagrams, mir,
newHead),
MatchboxXCombData(newME) {
flushCaches();
}
void MatchboxXCombGroup::clean() {
StdXCombGroup::clean();
flushCaches();
}
void MatchboxXCombGroup::persistentOutput(PersistentOStream & os) const {
MatchboxXCombData::persistentOutput(os);
}
void MatchboxXCombGroup::persistentInput(PersistentIStream & is, int version) {
MatchboxXCombData::persistentInput(is,version);
}
// *** 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<MatchboxXCombGroup,StdXCombGroup>
describeHerwigMatchboxXCombGroup("Herwig::MatchboxXCombGroup", "Herwig.so");
void MatchboxXCombGroup::Init() {
static ClassDocumentation<MatchboxXCombGroup> documentation
("MatchboxXCombGroup extents StdXCombGroup.");
}
diff --git a/MatrixElement/Matchbox/Utility/MatchboxXCombGroup.h b/MatrixElement/Matchbox/Utility/MatchboxXCombGroup.h
--- a/MatrixElement/Matchbox/Utility/MatchboxXCombGroup.h
+++ b/MatrixElement/Matchbox/Utility/MatchboxXCombGroup.h
@@ -1,102 +1,96 @@
// -*- C++ -*-
//
// MatchboxXCombGroup.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_MatchboxXCombGroup_H
#define Herwig_MatchboxXCombGroup_H
//
// This is the declaration of the MatchboxXCombGroup class.
//
#include "ThePEG/Handlers/StdXCombGroup.h"
#include "ThePEG/MatrixElement/MEGroup.h"
#include "Herwig/MatrixElement/Matchbox/Utility/MatchboxXCombData.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief Matchbox extensions to StandardXComb
*/
class MatchboxXCombGroup: public StdXCombGroup, public MatchboxXCombData {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* Standard constructor.
*/
MatchboxXCombGroup(Energy newMaxEnergy, const cPDPair & inc,
tEHPtr newEventHandler,tSubHdlPtr newSubProcessHandler,
tPExtrPtr newExtractor, tCascHdlPtr newCKKW,
const PBPair & newPartonBins, tCutsPtr newCuts, tMEGroupPtr newME,
const DiagramVector & newDiagrams, bool mir,
tStdXCombPtr newHead = tStdXCombPtr());
/**
* Default constructor.
*/
MatchboxXCombGroup();
-
- /**
- * Destructor.
- */
- virtual ~MatchboxXCombGroup();
-
//@}
public:
/**
* Reset all saved data about last generated phasespace point;
*/
virtual void clean();
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();
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MatchboxXCombGroup & operator=(const MatchboxXCombGroup &) = delete;
};
}
#endif /* Herwig_MatchboxXCombGroup_H */
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc b/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis.cc
@@ -1,414 +1,409 @@
// -*- C++ -*-
//
// SimpleColourBasis.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the SimpleColourBasis class.
//
#include "SimpleColourBasis.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-SimpleColourBasis::SimpleColourBasis() {}
-
-SimpleColourBasis::~SimpleColourBasis() {}
-
IBPtr SimpleColourBasis::clone() const {
return new_ptr(*this);
}
IBPtr SimpleColourBasis::fullclone() const {
return new_ptr(*this);
}
size_t SimpleColourBasis::prepareBasis(const vector<PDT::Colour>& basis) {
if ( id33bar.empty() )
makeIds();
if ( basis == id88 || basis == id33bar || basis == id33bar8 )
return 1;
if ( basis == id888 || basis == id33bar88 || basis == id33bar33bar )
return 2;
if ( basis == id8888 )
return 6;
throw Exception() << "SimpleColourBasis::prepareBasis(): Cannot handle colour configuration" << Exception::runerror;
return 0;
}
double SimpleColourBasis::scalarProduct(size_t a, size_t b,
const vector<PDT::Colour>& abBasis) const {
if ( id33bar.empty() )
makeIds();
double Nc = SM().Nc();
double Nc2 = sqr(Nc);
double Nc3 = Nc*Nc2;
double Nc4 = sqr(Nc2);
double Nc6 = Nc2*Nc4;
if ( a > b )
swap(a,b);
if ( !largeN() ) {
if ( abBasis == id88 ) {
return ( Nc2 - 1. )/4.;
}
if ( abBasis == id33bar ) {
return Nc;
}
if ( abBasis == id888 ) {
if ( a == b )
return ( Nc4 - 3.*Nc2 + 2. )/(8.*Nc);
return -( Nc2 - 1. )/(4.*Nc);
}
if ( abBasis == id33bar8 ) {
return ( Nc2 - 1. )/2.;
}
if ( abBasis == id8888 ) {
if ( a == b )
return ( Nc6 - 4.*Nc4 + 6.*Nc2 - 3. )/(16.*Nc2);
if ( ( a == 0 && b == 1 ) ||
( a == 2 && b == 3 ) ||
( a == 4 && b == 5 ) )
return ( Nc4 + 2.*Nc2 - 3. )/(16.*Nc2);
return -( Nc2 - 4. + 3./Nc2 )/16.;
}
if ( abBasis == id33bar88 ) {
if ( a == b )
return ( Nc4 - 2.*Nc2 + 1 )/(4.*Nc);
return -( Nc2 - 1. )/(4.*Nc);
}
if ( abBasis == id33bar33bar ) {
if ( a == b )
return Nc2;
return Nc;
}
} else {
if ( a != b )
return 0.;
if ( abBasis == id88 ) {
return Nc2/4.;
}
if ( abBasis == id33bar ) {
return Nc;
}
if ( abBasis == id888 ) {
return Nc3/8.;
}
if ( abBasis == id33bar8 ) {
return Nc2/2.;
}
if ( abBasis == id8888 ) {
return Nc4/16.;
}
if ( abBasis == id33bar88 ) {
return Nc3/4.;
}
if ( abBasis == id33bar33bar ) {
return Nc2;
}
}
throw Exception() << "SimpleColourBasis::scalarProduct(): Cannot handle colour configuration" << Exception::runerror;
}
double SimpleColourBasis::tMatrixElement(size_t i, size_t a,
size_t b,
const vector<PDT::Colour>&,
const vector<PDT::Colour>& bBasis,
#ifndef NDEBUG
size_t k, size_t l,
#else
size_t , size_t ,
#endif
const map<size_t,size_t>& dict) const {
// Check indices k and l
assert( k == i );
assert( l == bBasis.size() );
// Check that dict is the standardMap
assert( dict.size()+1 == bBasis.size() );
map<size_t,size_t>::const_iterator tmp;
for ( size_t ii = 0; ii < bBasis.size(); ii++ )
if ( ii != i ) {
tmp = dict.find(ii);
assert( tmp != dict.end() );
assert( tmp->second == ii );
}
if ( id33bar.empty() )
makeIds();
if ( bBasis == id88 ) {
if ( i == 0 )
return a == 0 ? -1. : 1.;
else
return a == 0 ? 1. : -1.;
}
if ( bBasis == id33bar ) {
return i == 0 ? 1. : -1.;
}
if ( bBasis == id888 ) {
if ( i == 0 ) {
if ( a == 3 && b == 0 )
return 1.;
if ( a == 0 && b == 0 )
return -1.;
if ( a == 1 && b == 1 )
return 1.;
if ( a == 2 && b == 1 )
return -1.;
}
if ( i == 1 ) {
if ( a == 4 && b == 0 )
return 1.;
if ( a == 3 && b == 0 )
return -1.;
if ( a == 2 && b == 1 )
return 1.;
if ( a == 5 && b == 1 )
return -1.;
}
if ( i == 2 ) {
if ( a == 0 && b == 0 )
return 1.;
if ( a == 4 && b == 0 )
return -1.;
if ( a == 5 && b == 1 )
return 1.;
if ( a == 1 && b == 1 )
return -1.;
}
return 0.;
}
if ( bBasis == id33bar8 ) {
if ( i == 0 )
return a == 1 ? 1. : 0.;
if ( i == 1 )
return a == 0 ? -1. : 0.;
if ( i == 2 )
return a == 0 ? 1. : -1.;
}
throw Exception() << "SimpleColourBasis::tMatrixElement(): Cannot handle colour configuration" << Exception::runerror;
return 0.;
}
bool SimpleColourBasis::colourConnected(const cPDVector& sub,
const vector<PDT::Colour>& basis,
const pair<int,bool>& i,
const pair<int,bool>& j,
size_t a) const {
if ( id33bar.empty() )
makeIds();
// translate process to basis ids
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= indexMap().find(sub);
assert(trans != indexMap().end());
int idColoured = i.second ? j.first : i.first;
idColoured = trans->second.find(idColoured)->second;
int idAntiColoured = i.second ? i.first : j.first;
idAntiColoured = trans->second.find(idAntiColoured)->second;
if ( basis == id88 ) {
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
}
if ( basis == id33bar ) {
return
idColoured == 0 && idAntiColoured == 1;
}
if ( basis == id888 ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 0 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
}
if ( basis == id33bar8 ) {
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 );
}
if ( basis == id8888 ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 0 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
if ( a == 2 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 0 );
if ( a == 3 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 0 );
if ( a == 4 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 0 );
if ( a == 5 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 1 ) ||
( idColoured == 1 && idAntiColoured == 0 );
}
if ( basis == id33bar88 ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 1 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 3 && idAntiColoured == 2 ) ||
( idColoured == 2 && idAntiColoured == 1 );
}
if ( basis == id33bar33bar ) {
if ( a == 0 )
return
( idColoured == 0 && idAntiColoured == 1 ) ||
( idColoured == 2 && idAntiColoured == 3 );
if ( a == 1 )
return
( idColoured == 0 && idAntiColoured == 3 ) ||
( idColoured == 2 && idAntiColoured == 1 );
}
return false;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void SimpleColourBasis::makeIds() const {
id88.push_back(PDT::Colour8);
id88.push_back(PDT::Colour8);
id33bar.push_back(PDT::Colour3);
id33bar.push_back(PDT::Colour3bar);
id888.push_back(PDT::Colour8);
id888.push_back(PDT::Colour8);
id888.push_back(PDT::Colour8);
id33bar8.push_back(PDT::Colour3);
id33bar8.push_back(PDT::Colour3bar);
id33bar8.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id8888.push_back(PDT::Colour8);
id33bar88.push_back(PDT::Colour3);
id33bar88.push_back(PDT::Colour3bar);
id33bar88.push_back(PDT::Colour8);
id33bar88.push_back(PDT::Colour8);
id33bar33bar.push_back(PDT::Colour3);
id33bar33bar.push_back(PDT::Colour3bar);
id33bar33bar.push_back(PDT::Colour3);
id33bar33bar.push_back(PDT::Colour3bar);
}
void SimpleColourBasis::persistentOutput(PersistentOStream &) const {}
void SimpleColourBasis::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<SimpleColourBasis,ColourBasis>
describeHerwigSimpleColourBasis("Herwig::SimpleColourBasis", "Herwig.so");
void SimpleColourBasis::Init() {
static ClassDocumentation<SimpleColourBasis> documentation
("SimpleColourBasis implements the colour algebra needed for "
"electroweak boson and electroweak boson + jet production at NLO. It mainly "
"serves as an example for the general ColourBasis interface.");
}
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis.h b/MatrixElement/Matchbox/Utility/SimpleColourBasis.h
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis.h
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis.h
@@ -1,209 +1,194 @@
// -*- C++ -*-
//
// SimpleColourBasis.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_SimpleColourBasis_H
#define Herwig_SimpleColourBasis_H
//
// This is the declaration of the SimpleColourBasis class.
//
#include "Herwig/MatrixElement/Matchbox/Utility/ColourBasis.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief SimpleColourBasis implements the colour algebra needed for
* electroweak boson and electroweak boson + jet production at NLO. It
* mainly serves as an example for the general ColourBasis interface.
*
*/
class SimpleColourBasis: public ColourBasis {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- SimpleColourBasis();
-
- /**
- * The destructor.
- */
- virtual ~SimpleColourBasis();
- //@}
-
-public:
-
/**
* Prepare the basis for the normal ordered legs and return the
* dimensionality of the basis.
*/
virtual size_t prepareBasis(const vector<PDT::Colour>&);
/**
* Return the scalar product of basis tensors labelled a and b in
* the basis used for the given normal ordered legs.
*/
virtual double scalarProduct(size_t a, size_t b,
const vector<PDT::Colour>& abBasis) const;
/**
* Return the matrix element of a colour charge
* <c_{n+1,a}|T_i|c_{n,b}> between basis tensors a and b, with
* respect to aBasis and bBasis
*/
virtual double tMatrixElement(size_t i, size_t a, size_t b,
const vector<PDT::Colour>& aBasis,
const vector<PDT::Colour>& bBasis,
size_t k, size_t l,
const map<size_t,size_t>& dict
) const;
virtual double sMatrixElement(size_t, size_t, size_t,
const vector<PDT::Colour>&,
const vector<PDT::Colour>&,
size_t, size_t,
const map<size_t,size_t>&
) const {
assert( 0 == 1 );
return 0;
}
/**
* Return true, if this colour basis supports gluon splittings.
*/
virtual bool canSplitGluons() const {
return false;
}
/**
* Return true, if a large-N colour connection exists for the
* given external legs and basis tensor.
*/
virtual bool colourConnected(const cPDVector&,
const vector<PDT::Colour>&,
const pair<int,bool>&,
const pair<int,bool>&,
size_t) const;
/**
* Return true, if the colour basis is capable of assigning colour
* flows.
*/
virtual bool haveColourFlows() const { return true; }
/**
* Create ids for bases
*/
void makeIds() 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:
/**
* id for 88
*/
mutable vector<PDT::Colour> id88;
/**
* id for 33bar
*/
mutable vector<PDT::Colour> id33bar;
/**
* id for 888
*/
mutable vector<PDT::Colour> id888;
/**
* id for 33bar8
*/
mutable vector<PDT::Colour> id33bar8;
/**
* id for 8888
*/
mutable vector<PDT::Colour> id8888;
/**
* id for 33bar88
*/
mutable vector<PDT::Colour> id33bar88;
/**
* id for 33bar33bar
*/
mutable vector<PDT::Colour> id33bar33bar;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
SimpleColourBasis & operator=(const SimpleColourBasis &) = delete;
};
}
#endif /* Herwig_SimpleColourBasis_H */
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.cc
@@ -1,2882 +1,2877 @@
// -*- C++ -*-
//
// SimpleColourBasis2.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the SimpleColourBasis2 class.
//
#include "SimpleColourBasis2.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
-
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
-SimpleColourBasis2::SimpleColourBasis2() {}
-
-SimpleColourBasis2::~SimpleColourBasis2() {}
-
IBPtr SimpleColourBasis2::clone() const {
return new_ptr(*this);
}
IBPtr SimpleColourBasis2::fullclone() const {
return new_ptr(*this);
}
size_t SimpleColourBasis2::prepareBasis(const vector<PDT::Colour>& basis) {
if ( id33bar.empty() )
makeIds();
if ( basis == id88 ) {
return 1;
}
if ( basis == id33bar ) {
return 1;
}
if ( basis == id888 ) {
return 2;
}
if ( basis == id33bar8 ) {
return 1;
}
if ( basis == id8888 ) {
return 9;
}
if ( basis == id33bar88 ) {
return 3;
}
if ( basis == id33bar33bar ) {
return 2;
}
if ( basis == id88888 ) {
return 44;
}
if ( basis == id33bar888 ) {
return 11;
}
if ( basis == id33bar33bar8 ) {
return 4;
}
throw Exception() << "SimpleColourBasis2::prepareBasis(): Cannot handle colour configuration" << Exception::runerror;
return 0;
}
double SimpleColourBasis2::scalarProduct(size_t a, size_t b,
const vector<PDT::Colour>& basis) const {
if ( id33bar.empty() )
makeIds();
double Nc = SM().Nc();
double Nc2 = sqr(Nc);
double Nc3 = Nc*Nc2;
double Nc4 = sqr(Nc2);
double Nc5 = Nc*Nc4;
double Nc6 = Nc2*Nc4;
double Nc8 = Nc2*Nc6;
if ( a > b )
swap(a,b);
if ( !largeN() ) {
if ( basis == id88 ) {
if( a == 0 && b == 0 )
return (-1 + Nc2)/4.;
}
if ( basis == id33bar ) {
if( a == 0 && b == 0 )
return Nc;
}
if ( basis == id888 ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) )
return (2 - 3*Nc2 + Nc4)/(8.*Nc);
if( ( a == 0 ) && ( b == 1 ) )
return -(-1 + Nc2)/(4.*Nc);
}
if ( basis == id33bar8 ) {
if( a == 0 && b == 0 )
return (-1 + Nc2)/2.;
}
if ( basis == id8888 ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) ||
( a == 2 && b == 2 ) )
return sqr(-1 + Nc2)/16.;
if( ( a == 0 && b == 1 ) ||
( a == 0 && b == 2 ) ||
( a == 1 && b == 2 ) )
return (-1 + Nc2)/16.;
if( ( a == 0 && b == 3 ) ||
( a == 0 && b == 5 ) ||
( a == 0 && b == 7 ) ||
( a == 0 && b == 8 ) ||
( a == 1 && b == 4 ) ||
( a == 1 && b == 5 ) ||
( a == 1 && b == 6 ) ||
( a == 1 && b == 7 ) ||
( a == 2 && b == 3 ) ||
( a == 2 && b == 4 ) ||
( a == 2 && b == 6 ) ||
( a == 2 && b == 8 ) )
return sqr(-1 + Nc2)/(16.*Nc);
if( ( a == 0 && b == 4 ) ||
( a == 0 && b == 6 ) ||
( a == 1 && b == 3 ) ||
( a == 1 && b == 8 ) ||
( a == 2 && b == 5 ) ||
( a == 2 && b == 7 ) )
return -(-1 + Nc2)/(16.*Nc);
if( ( a == 3 && b == 3 ) ||
( a == 4 && b == 4 ) ||
( a == 5 && b == 5 ) ||
( a == 6 && b == 6 ) ||
( a == 7 && b == 7 ) ||
( a == 8 && b == 8 ) )
return (-3 + 6*Nc2 - 4*Nc4 + Nc6)/(16.*Nc2);
if( ( a == 3 && b == 4 ) ||
( a == 3 && b == 5 ) ||
( a == 3 && b == 6 ) ||
( a == 3 && b == 7 ) ||
( a == 4 && b == 5 ) ||
( a == 4 && b == 7 ) ||
( a == 4 && b == 8 ) ||
( a == 5 && b == 6 ) ||
( a == 5 && b == 8 ) ||
( a == 6 && b == 7 ) ||
( a == 6 && b == 8 ) ||
( a == 7 && b == 8 ) )
return (4 - 3/Nc2 - Nc2)/16.;
if( ( a == 3 && b == 8 ) ||
( a == 4 && b == 6 ) ||
( a == 5 && b == 7 ) )
return (-3 + 2*Nc2 + Nc4)/(16.*Nc2);
}
if ( basis == id33bar88 ) {
if( a == 0 && b == 0 )
return (Nc*(-1 + Nc2))/4.;
if( ( a == 0 && b == 1 ) ||
( a == 0 && b == 2 ) )
return (-1 + Nc2)/4.;
if( ( a == 1 && b == 1 ) ||
( a == 2 && b == 2 ) )
return sqr(-1 + Nc2)/(4.*Nc);
if( a == 1 && b == 2 )
return -(-1 + Nc2)/(4.*Nc);
}
if ( basis == id33bar33bar ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) )
return Nc2;
if( a == 0 && b == 1 )
return Nc;
}
if ( basis == id88888 ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) ||
( a == 2 && b == 2 ) ||
( a == 3 && b == 3 ) ||
( a == 4 && b == 4 ) ||
( a == 5 && b == 5 ) ||
( a == 6 && b == 6 ) ||
( a == 7 && b == 7 ) ||
( a == 8 && b == 8 ) ||
( a == 9 && b == 9 ) ||
( a == 10 && b == 10 ) ||
( a == 11 && b == 11 ) ||
( a == 12 && b == 12 ) ||
( a == 13 && b == 13 ) ||
( a == 14 && b == 14 ) ||
( a == 15 && b == 15 ) ||
( a == 16 && b == 16 ) ||
( a == 17 && b == 17 ) ||
( a == 18 && b == 18 ) ||
( a == 19 && b == 19 ) )
return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc);
if( ( a == 0 && b == 1 ) ||
( a == 0 && b == 2 ) ||
( a == 0 && b == 7 ) ||
( a == 0 && b == 10 ) ||
( a == 0 && b == 12 ) ||
( a == 0 && b == 13 ) ||
( a == 1 && b == 2 ) ||
( a == 1 && b == 4 ) ||
( a == 1 && b == 11 ) ||
( a == 1 && b == 14 ) ||
( a == 1 && b == 15 ) ||
( a == 2 && b == 5 ) ||
( a == 2 && b == 8 ) ||
( a == 2 && b == 16 ) ||
( a == 2 && b == 17 ) ||
( a == 3 && b == 4 ) ||
( a == 3 && b == 5 ) ||
( a == 3 && b == 6 ) ||
( a == 3 && b == 9 ) ||
( a == 3 && b == 14 ) ||
( a == 3 && b == 16 ) ||
( a == 4 && b == 5 ) ||
( a == 4 && b == 11 ) ||
( a == 4 && b == 12 ) ||
( a == 4 && b == 18 ) ||
( a == 5 && b == 8 ) ||
( a == 5 && b == 13 ) ||
( a == 5 && b == 19 ) ||
( a == 6 && b == 7 ) ||
( a == 6 && b == 8 ) ||
( a == 6 && b == 9 ) ||
( a == 6 && b == 12 ) ||
( a == 6 && b == 17 ) ||
( a == 7 && b == 8 ) ||
( a == 7 && b == 10 ) ||
( a == 7 && b == 14 ) ||
( a == 7 && b == 19 ) ||
( a == 8 && b == 15 ) ||
( a == 8 && b == 18 ) ||
( a == 9 && b == 10 ) ||
( a == 9 && b == 11 ) ||
( a == 9 && b == 13 ) ||
( a == 9 && b == 15 ) ||
( a == 10 && b == 11 ) ||
( a == 10 && b == 16 ) ||
( a == 10 && b == 18 ) ||
( a == 11 && b == 17 ) ||
( a == 11 && b == 19 ) ||
( a == 12 && b == 13 ) ||
( a == 12 && b == 17 ) ||
( a == 12 && b == 18 ) ||
( a == 13 && b == 15 ) ||
( a == 13 && b == 19 ) ||
( a == 14 && b == 15 ) ||
( a == 14 && b == 16 ) ||
( a == 14 && b == 19 ) ||
( a == 15 && b == 18 ) ||
( a == 16 && b == 17 ) ||
( a == 16 && b == 18 ) ||
( a == 17 && b == 19 ) )
return (2 - 3*Nc2 + Nc4)/(32.*Nc);
if( ( a == 0 && b == 3 ) ||
( a == 1 && b == 6 ) ||
( a == 2 && b == 9 ) ||
( a == 4 && b == 7 ) ||
( a == 5 && b == 10 ) ||
( a == 8 && b == 11 ) ||
( a == 12 && b == 14 ) ||
( a == 13 && b == 16 ) ||
( a == 15 && b == 17 ) ||
( a == 18 && b == 19 ) )
return -sqr(-1 + Nc2)/(16.*Nc);
if( ( a == 0 && b == 4 ) ||
( a == 0 && b == 5 ) ||
( a == 0 && b == 6 ) ||
( a == 0 && b == 9 ) ||
( a == 0 && b == 14 ) ||
( a == 0 && b == 16 ) ||
( a == 1 && b == 3 ) ||
( a == 1 && b == 7 ) ||
( a == 1 && b == 8 ) ||
( a == 1 && b == 9 ) ||
( a == 1 && b == 12 ) ||
( a == 1 && b == 17 ) ||
( a == 2 && b == 3 ) ||
( a == 2 && b == 6 ) ||
( a == 2 && b == 10 ) ||
( a == 2 && b == 11 ) ||
( a == 2 && b == 13 ) ||
( a == 2 && b == 15 ) ||
( a == 3 && b == 7 ) ||
( a == 3 && b == 10 ) ||
( a == 3 && b == 12 ) ||
( a == 3 && b == 13 ) ||
( a == 4 && b == 6 ) ||
( a == 4 && b == 8 ) ||
( a == 4 && b == 10 ) ||
( a == 4 && b == 14 ) ||
( a == 4 && b == 19 ) ||
( a == 5 && b == 7 ) ||
( a == 5 && b == 9 ) ||
( a == 5 && b == 11 ) ||
( a == 5 && b == 16 ) ||
( a == 5 && b == 18 ) ||
( a == 6 && b == 11 ) ||
( a == 6 && b == 14 ) ||
( a == 6 && b == 15 ) ||
( a == 7 && b == 11 ) ||
( a == 7 && b == 12 ) ||
( a == 7 && b == 18 ) ||
( a == 8 && b == 9 ) ||
( a == 8 && b == 10 ) ||
( a == 8 && b == 17 ) ||
( a == 8 && b == 19 ) ||
( a == 9 && b == 16 ) ||
( a == 9 && b == 17 ) ||
( a == 10 && b == 13 ) ||
( a == 10 && b == 19 ) ||
( a == 11 && b == 15 ) ||
( a == 11 && b == 18 ) ||
( a == 12 && b == 15 ) ||
( a == 12 && b == 16 ) ||
( a == 12 && b == 19 ) ||
( a == 13 && b == 14 ) ||
( a == 13 && b == 17 ) ||
( a == 13 && b == 18 ) ||
( a == 14 && b == 17 ) ||
( a == 14 && b == 18 ) ||
( a == 15 && b == 16 ) ||
( a == 15 && b == 19 ) ||
( a == 16 && b == 19 ) ||
( a == 17 && b == 18 ) )
return -(-1 + Nc2)/(16.*Nc);
if( ( a == 0 && b == 8 ) ||
( a == 0 && b == 11 ) ||
( a == 0 && b == 15 ) ||
( a == 0 && b == 17 ) ||
( a == 0 && b == 18 ) ||
( a == 0 && b == 19 ) ||
( a == 1 && b == 5 ) ||
( a == 1 && b == 10 ) ||
( a == 1 && b == 13 ) ||
( a == 1 && b == 16 ) ||
( a == 1 && b == 18 ) ||
( a == 1 && b == 19 ) ||
( a == 2 && b == 4 ) ||
( a == 2 && b == 7 ) ||
( a == 2 && b == 12 ) ||
( a == 2 && b == 14 ) ||
( a == 2 && b == 18 ) ||
( a == 2 && b == 19 ) ||
( a == 3 && b == 8 ) ||
( a == 3 && b == 11 ) ||
( a == 3 && b == 15 ) ||
( a == 3 && b == 17 ) ||
( a == 3 && b == 18 ) ||
( a == 3 && b == 19 ) ||
( a == 4 && b == 9 ) ||
( a == 4 && b == 13 ) ||
( a == 4 && b == 15 ) ||
( a == 4 && b == 16 ) ||
( a == 4 && b == 17 ) ||
( a == 5 && b == 6 ) ||
( a == 5 && b == 12 ) ||
( a == 5 && b == 14 ) ||
( a == 5 && b == 15 ) ||
( a == 5 && b == 17 ) ||
( a == 6 && b == 10 ) ||
( a == 6 && b == 13 ) ||
( a == 6 && b == 16 ) ||
( a == 6 && b == 18 ) ||
( a == 6 && b == 19 ) ||
( a == 7 && b == 9 ) ||
( a == 7 && b == 13 ) ||
( a == 7 && b == 15 ) ||
( a == 7 && b == 16 ) ||
( a == 7 && b == 17 ) ||
( a == 8 && b == 12 ) ||
( a == 8 && b == 13 ) ||
( a == 8 && b == 14 ) ||
( a == 8 && b == 16 ) ||
( a == 9 && b == 12 ) ||
( a == 9 && b == 14 ) ||
( a == 9 && b == 18 ) ||
( a == 9 && b == 19 ) ||
( a == 10 && b == 12 ) ||
( a == 10 && b == 14 ) ||
( a == 10 && b == 15 ) ||
( a == 10 && b == 17 ) ||
( a == 11 && b == 12 ) ||
( a == 11 && b == 13 ) ||
( a == 11 && b == 14 ) ||
( a == 11 && b == 16 ) )
return 0;
if( ( a == 0 && b == 20 ) ||
( a == 0 && b == 21 ) ||
( a == 0 && b == 23 ) ||
( a == 0 && b == 25 ) ||
( a == 0 && b == 36 ) ||
( a == 0 && b == 42 ) ||
( a == 1 && b == 21 ) ||
( a == 1 && b == 22 ) ||
( a == 1 && b == 23 ) ||
( a == 1 && b == 24 ) ||
( a == 1 && b == 30 ) ||
( a == 1 && b == 40 ) ||
( a == 2 && b == 20 ) ||
( a == 2 && b == 22 ) ||
( a == 2 && b == 24 ) ||
( a == 2 && b == 25 ) ||
( a == 2 && b == 28 ) ||
( a == 2 && b == 34 ) ||
( a == 3 && b == 26 ) ||
( a == 3 && b == 27 ) ||
( a == 3 && b == 29 ) ||
( a == 3 && b == 31 ) ||
( a == 3 && b == 37 ) ||
( a == 3 && b == 43 ) ||
( a == 4 && b == 24 ) ||
( a == 4 && b == 27 ) ||
( a == 4 && b == 28 ) ||
( a == 4 && b == 29 ) ||
( a == 4 && b == 30 ) ||
( a == 4 && b == 38 ) ||
( a == 5 && b == 22 ) ||
( a == 5 && b == 26 ) ||
( a == 5 && b == 28 ) ||
( a == 5 && b == 30 ) ||
( a == 5 && b == 31 ) ||
( a == 5 && b == 32 ) ||
( a == 6 && b == 31 ) ||
( a == 6 && b == 32 ) ||
( a == 6 && b == 33 ) ||
( a == 6 && b == 35 ) ||
( a == 6 && b == 37 ) ||
( a == 6 && b == 41 ) ||
( a == 7 && b == 25 ) ||
( a == 7 && b == 33 ) ||
( a == 7 && b == 34 ) ||
( a == 7 && b == 35 ) ||
( a == 7 && b == 36 ) ||
( a == 7 && b == 39 ) ||
( a == 8 && b == 20 ) ||
( a == 8 && b == 26 ) ||
( a == 8 && b == 32 ) ||
( a == 8 && b == 34 ) ||
( a == 8 && b == 36 ) ||
( a == 8 && b == 37 ) ||
( a == 9 && b == 29 ) ||
( a == 9 && b == 35 ) ||
( a == 9 && b == 38 ) ||
( a == 9 && b == 39 ) ||
( a == 9 && b == 41 ) ||
( a == 9 && b == 43 ) ||
( a == 10 && b == 23 ) ||
( a == 10 && b == 33 ) ||
( a == 10 && b == 39 ) ||
( a == 10 && b == 40 ) ||
( a == 10 && b == 41 ) ||
( a == 10 && b == 42 ) ||
( a == 11 && b == 21 ) ||
( a == 11 && b == 27 ) ||
( a == 11 && b == 38 ) ||
( a == 11 && b == 40 ) ||
( a == 11 && b == 42 ) ||
( a == 11 && b == 43 ) ||
( a == 12 && b == 20 ) ||
( a == 12 && b == 28 ) ||
( a == 12 && b == 32 ) ||
( a == 12 && b == 38 ) ||
( a == 12 && b == 41 ) ||
( a == 12 && b == 42 ) ||
( a == 13 && b == 21 ) ||
( a == 13 && b == 30 ) ||
( a == 13 && b == 32 ) ||
( a == 13 && b == 35 ) ||
( a == 13 && b == 36 ) ||
( a == 13 && b == 38 ) ||
( a == 14 && b == 22 ) ||
( a == 14 && b == 26 ) ||
( a == 14 && b == 34 ) ||
( a == 14 && b == 39 ) ||
( a == 14 && b == 40 ) ||
( a == 14 && b == 43 ) ||
( a == 15 && b == 23 ) ||
( a == 15 && b == 26 ) ||
( a == 15 && b == 29 ) ||
( a == 15 && b == 30 ) ||
( a == 15 && b == 36 ) ||
( a == 15 && b == 39 ) ||
( a == 16 && b == 24 ) ||
( a == 16 && b == 27 ) ||
( a == 16 && b == 33 ) ||
( a == 16 && b == 34 ) ||
( a == 16 && b == 37 ) ||
( a == 16 && b == 40 ) ||
( a == 17 && b == 25 ) ||
( a == 17 && b == 27 ) ||
( a == 17 && b == 28 ) ||
( a == 17 && b == 31 ) ||
( a == 17 && b == 33 ) ||
( a == 17 && b == 42 ) ||
( a == 18 && b == 20 ) ||
( a == 18 && b == 23 ) ||
( a == 18 && b == 24 ) ||
( a == 18 && b == 29 ) ||
( a == 18 && b == 37 ) ||
( a == 18 && b == 41 ) ||
( a == 19 && b == 21 ) ||
( a == 19 && b == 22 ) ||
( a == 19 && b == 25 ) ||
( a == 19 && b == 31 ) ||
( a == 19 && b == 35 ) ||
( a == 19 && b == 43 ) )
return ((-2 + Nc2)*sqr(-1 + Nc2))/(32.*Nc2);
if( ( a == 0 && b == 22 ) ||
( a == 0 && b == 24 ) ||
( a == 0 && b == 32 ) ||
( a == 0 && b == 33 ) ||
( a == 0 && b == 38 ) ||
( a == 0 && b == 39 ) ||
( a == 1 && b == 20 ) ||
( a == 1 && b == 25 ) ||
( a == 1 && b == 26 ) ||
( a == 1 && b == 27 ) ||
( a == 1 && b == 38 ) ||
( a == 1 && b == 39 ) ||
( a == 2 && b == 21 ) ||
( a == 2 && b == 23 ) ||
( a == 2 && b == 26 ) ||
( a == 2 && b == 27 ) ||
( a == 2 && b == 32 ) ||
( a == 2 && b == 33 ) ||
( a == 3 && b == 28 ) ||
( a == 3 && b == 30 ) ||
( a == 3 && b == 34 ) ||
( a == 3 && b == 35 ) ||
( a == 3 && b == 40 ) ||
( a == 3 && b == 41 ) ||
( a == 4 && b == 20 ) ||
( a == 4 && b == 21 ) ||
( a == 4 && b == 26 ) ||
( a == 4 && b == 31 ) ||
( a == 4 && b == 40 ) ||
( a == 4 && b == 41 ) ||
( a == 5 && b == 20 ) ||
( a == 5 && b == 21 ) ||
( a == 5 && b == 27 ) ||
( a == 5 && b == 29 ) ||
( a == 5 && b == 34 ) ||
( a == 5 && b == 35 ) ||
( a == 6 && b == 28 ) ||
( a == 6 && b == 29 ) ||
( a == 6 && b == 34 ) ||
( a == 6 && b == 36 ) ||
( a == 6 && b == 42 ) ||
( a == 6 && b == 43 ) ||
( a == 7 && b == 22 ) ||
( a == 7 && b == 23 ) ||
( a == 7 && b == 32 ) ||
( a == 7 && b == 37 ) ||
( a == 7 && b == 42 ) ||
( a == 7 && b == 43 ) ||
( a == 8 && b == 22 ) ||
( a == 8 && b == 23 ) ||
( a == 8 && b == 28 ) ||
( a == 8 && b == 29 ) ||
( a == 8 && b == 33 ) ||
( a == 8 && b == 35 ) ||
( a == 9 && b == 30 ) ||
( a == 9 && b == 31 ) ||
( a == 9 && b == 36 ) ||
( a == 9 && b == 37 ) ||
( a == 9 && b == 40 ) ||
( a == 9 && b == 42 ) ||
( a == 10 && b == 24 ) ||
( a == 10 && b == 25 ) ||
( a == 10 && b == 36 ) ||
( a == 10 && b == 37 ) ||
( a == 10 && b == 38 ) ||
( a == 10 && b == 43 ) ||
( a == 11 && b == 24 ) ||
( a == 11 && b == 25 ) ||
( a == 11 && b == 30 ) ||
( a == 11 && b == 31 ) ||
( a == 11 && b == 39 ) ||
( a == 11 && b == 41 ) ||
( a == 12 && b == 21 ) ||
( a == 12 && b == 24 ) ||
( a == 12 && b == 29 ) ||
( a == 12 && b == 31 ) ||
( a == 12 && b == 33 ) ||
( a == 12 && b == 36 ) ||
( a == 13 && b == 20 ) ||
( a == 13 && b == 22 ) ||
( a == 13 && b == 29 ) ||
( a == 13 && b == 31 ) ||
( a == 13 && b == 39 ) ||
( a == 13 && b == 42 ) ||
( a == 14 && b == 23 ) ||
( a == 14 && b == 25 ) ||
( a == 14 && b == 27 ) ||
( a == 14 && b == 30 ) ||
( a == 14 && b == 35 ) ||
( a == 14 && b == 37 ) ||
( a == 15 && b == 20 ) ||
( a == 15 && b == 22 ) ||
( a == 15 && b == 35 ) ||
( a == 15 && b == 37 ) ||
( a == 15 && b == 38 ) ||
( a == 15 && b == 40 ) ||
( a == 16 && b == 23 ) ||
( a == 16 && b == 25 ) ||
( a == 16 && b == 26 ) ||
( a == 16 && b == 28 ) ||
( a == 16 && b == 41 ) ||
( a == 16 && b == 43 ) ||
( a == 17 && b == 21 ) ||
( a == 17 && b == 24 ) ||
( a == 17 && b == 32 ) ||
( a == 17 && b == 34 ) ||
( a == 17 && b == 41 ) ||
( a == 17 && b == 43 ) ||
( a == 18 && b == 26 ) ||
( a == 18 && b == 28 ) ||
( a == 18 && b == 33 ) ||
( a == 18 && b == 36 ) ||
( a == 18 && b == 38 ) ||
( a == 18 && b == 40 ) ||
( a == 19 && b == 27 ) ||
( a == 19 && b == 30 ) ||
( a == 19 && b == 32 ) ||
( a == 19 && b == 34 ) ||
( a == 19 && b == 39 ) ||
( a == 19 && b == 42 ) )
return -(2 - 3*Nc2 + Nc4)/(32.*Nc2);
if( ( a == 0 && b == 26 ) ||
( a == 0 && b == 27 ) ||
( a == 0 && b == 29 ) ||
( a == 0 && b == 31 ) ||
( a == 0 && b == 37 ) ||
( a == 0 && b == 43 ) ||
( a == 1 && b == 31 ) ||
( a == 1 && b == 32 ) ||
( a == 1 && b == 33 ) ||
( a == 1 && b == 35 ) ||
( a == 1 && b == 37 ) ||
( a == 1 && b == 41 ) ||
( a == 2 && b == 29 ) ||
( a == 2 && b == 35 ) ||
( a == 2 && b == 38 ) ||
( a == 2 && b == 39 ) ||
( a == 2 && b == 41 ) ||
( a == 2 && b == 43 ) ||
( a == 3 && b == 20 ) ||
( a == 3 && b == 21 ) ||
( a == 3 && b == 23 ) ||
( a == 3 && b == 25 ) ||
( a == 3 && b == 36 ) ||
( a == 3 && b == 42 ) ||
( a == 4 && b == 25 ) ||
( a == 4 && b == 33 ) ||
( a == 4 && b == 34 ) ||
( a == 4 && b == 35 ) ||
( a == 4 && b == 36 ) ||
( a == 4 && b == 39 ) ||
( a == 5 && b == 23 ) ||
( a == 5 && b == 33 ) ||
( a == 5 && b == 39 ) ||
( a == 5 && b == 40 ) ||
( a == 5 && b == 41 ) ||
( a == 5 && b == 42 ) ||
( a == 6 && b == 21 ) ||
( a == 6 && b == 22 ) ||
( a == 6 && b == 23 ) ||
( a == 6 && b == 24 ) ||
( a == 6 && b == 30 ) ||
( a == 6 && b == 40 ) ||
( a == 7 && b == 24 ) ||
( a == 7 && b == 27 ) ||
( a == 7 && b == 28 ) ||
( a == 7 && b == 29 ) ||
( a == 7 && b == 30 ) ||
( a == 7 && b == 38 ) ||
( a == 8 && b == 21 ) ||
( a == 8 && b == 27 ) ||
( a == 8 && b == 38 ) ||
( a == 8 && b == 40 ) ||
( a == 8 && b == 42 ) ||
( a == 8 && b == 43 ) ||
( a == 9 && b == 20 ) ||
( a == 9 && b == 22 ) ||
( a == 9 && b == 24 ) ||
( a == 9 && b == 25 ) ||
( a == 9 && b == 28 ) ||
( a == 9 && b == 34 ) ||
( a == 10 && b == 22 ) ||
( a == 10 && b == 26 ) ||
( a == 10 && b == 28 ) ||
( a == 10 && b == 30 ) ||
( a == 10 && b == 31 ) ||
( a == 10 && b == 32 ) ||
( a == 11 && b == 20 ) ||
( a == 11 && b == 26 ) ||
( a == 11 && b == 32 ) ||
( a == 11 && b == 34 ) ||
( a == 11 && b == 36 ) ||
( a == 11 && b == 37 ) ||
( a == 12 && b == 22 ) ||
( a == 12 && b == 26 ) ||
( a == 12 && b == 34 ) ||
( a == 12 && b == 39 ) ||
( a == 12 && b == 40 ) ||
( a == 12 && b == 43 ) ||
( a == 13 && b == 24 ) ||
( a == 13 && b == 27 ) ||
( a == 13 && b == 33 ) ||
( a == 13 && b == 34 ) ||
( a == 13 && b == 37 ) ||
( a == 13 && b == 40 ) ||
( a == 14 && b == 20 ) ||
( a == 14 && b == 28 ) ||
( a == 14 && b == 32 ) ||
( a == 14 && b == 38 ) ||
( a == 14 && b == 41 ) ||
( a == 14 && b == 42 ) ||
( a == 15 && b == 25 ) ||
( a == 15 && b == 27 ) ||
( a == 15 && b == 28 ) ||
( a == 15 && b == 31 ) ||
( a == 15 && b == 33 ) ||
( a == 15 && b == 42 ) ||
( a == 16 && b == 21 ) ||
( a == 16 && b == 30 ) ||
( a == 16 && b == 32 ) ||
( a == 16 && b == 35 ) ||
( a == 16 && b == 36 ) ||
( a == 16 && b == 38 ) ||
( a == 17 && b == 23 ) ||
( a == 17 && b == 26 ) ||
( a == 17 && b == 29 ) ||
( a == 17 && b == 30 ) ||
( a == 17 && b == 36 ) ||
( a == 17 && b == 39 ) ||
( a == 18 && b == 21 ) ||
( a == 18 && b == 22 ) ||
( a == 18 && b == 25 ) ||
( a == 18 && b == 31 ) ||
( a == 18 && b == 35 ) ||
( a == 18 && b == 43 ) ||
( a == 19 && b == 20 ) ||
( a == 19 && b == 23 ) ||
( a == 19 && b == 24 ) ||
( a == 19 && b == 29 ) ||
( a == 19 && b == 37 ) ||
( a == 19 && b == 41 ) )
return -sqr(-1 + Nc2)/(16.*Nc2);
if( ( a == 0 && b == 28 ) ||
( a == 0 && b == 30 ) ||
( a == 0 && b == 34 ) ||
( a == 0 && b == 35 ) ||
( a == 0 && b == 40 ) ||
( a == 0 && b == 41 ) ||
( a == 1 && b == 28 ) ||
( a == 1 && b == 29 ) ||
( a == 1 && b == 34 ) ||
( a == 1 && b == 36 ) ||
( a == 1 && b == 42 ) ||
( a == 1 && b == 43 ) ||
( a == 2 && b == 30 ) ||
( a == 2 && b == 31 ) ||
( a == 2 && b == 36 ) ||
( a == 2 && b == 37 ) ||
( a == 2 && b == 40 ) ||
( a == 2 && b == 42 ) ||
( a == 3 && b == 22 ) ||
( a == 3 && b == 24 ) ||
( a == 3 && b == 32 ) ||
( a == 3 && b == 33 ) ||
( a == 3 && b == 38 ) ||
( a == 3 && b == 39 ) ||
( a == 4 && b == 22 ) ||
( a == 4 && b == 23 ) ||
( a == 4 && b == 32 ) ||
( a == 4 && b == 37 ) ||
( a == 4 && b == 42 ) ||
( a == 4 && b == 43 ) ||
( a == 5 && b == 24 ) ||
( a == 5 && b == 25 ) ||
( a == 5 && b == 36 ) ||
( a == 5 && b == 37 ) ||
( a == 5 && b == 38 ) ||
( a == 5 && b == 43 ) ||
( a == 6 && b == 20 ) ||
( a == 6 && b == 25 ) ||
( a == 6 && b == 26 ) ||
( a == 6 && b == 27 ) ||
( a == 6 && b == 38 ) ||
( a == 6 && b == 39 ) ||
( a == 7 && b == 20 ) ||
( a == 7 && b == 21 ) ||
( a == 7 && b == 26 ) ||
( a == 7 && b == 31 ) ||
( a == 7 && b == 40 ) ||
( a == 7 && b == 41 ) ||
( a == 8 && b == 24 ) ||
( a == 8 && b == 25 ) ||
( a == 8 && b == 30 ) ||
( a == 8 && b == 31 ) ||
( a == 8 && b == 39 ) ||
( a == 8 && b == 41 ) ||
( a == 9 && b == 21 ) ||
( a == 9 && b == 23 ) ||
( a == 9 && b == 26 ) ||
( a == 9 && b == 27 ) ||
( a == 9 && b == 32 ) ||
( a == 9 && b == 33 ) ||
( a == 10 && b == 20 ) ||
( a == 10 && b == 21 ) ||
( a == 10 && b == 27 ) ||
( a == 10 && b == 29 ) ||
( a == 10 && b == 34 ) ||
( a == 10 && b == 35 ) ||
( a == 11 && b == 22 ) ||
( a == 11 && b == 23 ) ||
( a == 11 && b == 28 ) ||
( a == 11 && b == 29 ) ||
( a == 11 && b == 33 ) ||
( a == 11 && b == 35 ) ||
( a == 12 && b == 23 ) ||
( a == 12 && b == 25 ) ||
( a == 12 && b == 27 ) ||
( a == 12 && b == 30 ) ||
( a == 12 && b == 35 ) ||
( a == 12 && b == 37 ) ||
( a == 13 && b == 23 ) ||
( a == 13 && b == 25 ) ||
( a == 13 && b == 26 ) ||
( a == 13 && b == 28 ) ||
( a == 13 && b == 41 ) ||
( a == 13 && b == 43 ) ||
( a == 14 && b == 21 ) ||
( a == 14 && b == 24 ) ||
( a == 14 && b == 29 ) ||
( a == 14 && b == 31 ) ||
( a == 14 && b == 33 ) ||
( a == 14 && b == 36 ) ||
( a == 15 && b == 21 ) ||
( a == 15 && b == 24 ) ||
( a == 15 && b == 32 ) ||
( a == 15 && b == 34 ) ||
( a == 15 && b == 41 ) ||
( a == 15 && b == 43 ) ||
( a == 16 && b == 20 ) ||
( a == 16 && b == 22 ) ||
( a == 16 && b == 29 ) ||
( a == 16 && b == 31 ) ||
( a == 16 && b == 39 ) ||
( a == 16 && b == 42 ) ||
( a == 17 && b == 20 ) ||
( a == 17 && b == 22 ) ||
( a == 17 && b == 35 ) ||
( a == 17 && b == 37 ) ||
( a == 17 && b == 38 ) ||
( a == 17 && b == 40 ) ||
( a == 18 && b == 27 ) ||
( a == 18 && b == 30 ) ||
( a == 18 && b == 32 ) ||
( a == 18 && b == 34 ) ||
( a == 18 && b == 39 ) ||
( a == 18 && b == 42 ) ||
( a == 19 && b == 26 ) ||
( a == 19 && b == 28 ) ||
( a == 19 && b == 33 ) ||
( a == 19 && b == 36 ) ||
( a == 19 && b == 38 ) ||
( a == 19 && b == 40 ) )
return (1 - 1/Nc2)/16.;
if( ( a == 20 && b == 20 ) ||
( a == 21 && b == 21 ) ||
( a == 22 && b == 22 ) ||
( a == 23 && b == 23 ) ||
( a == 24 && b == 24 ) ||
( a == 25 && b == 25 ) ||
( a == 26 && b == 26 ) ||
( a == 27 && b == 27 ) ||
( a == 28 && b == 28 ) ||
( a == 29 && b == 29 ) ||
( a == 30 && b == 30 ) ||
( a == 31 && b == 31 ) ||
( a == 32 && b == 32 ) ||
( a == 33 && b == 33 ) ||
( a == 34 && b == 34 ) ||
( a == 35 && b == 35 ) ||
( a == 36 && b == 36 ) ||
( a == 37 && b == 37 ) ||
( a == 38 && b == 38 ) ||
( a == 39 && b == 39 ) ||
( a == 40 && b == 40 ) ||
( a == 41 && b == 41 ) ||
( a == 42 && b == 42 ) ||
( a == 43 && b == 43 ) )
return (4 - 10*Nc2 + 10*Nc4 - 5*Nc6 + Nc8)/(32.*Nc3);
if( ( a == 20 && b == 21 ) ||
( a == 20 && b == 22 ) ||
( a == 20 && b == 26 ) ||
( a == 20 && b == 29 ) ||
( a == 20 && b == 38 ) ||
( a == 21 && b == 24 ) ||
( a == 21 && b == 27 ) ||
( a == 21 && b == 31 ) ||
( a == 21 && b == 32 ) ||
( a == 22 && b == 23 ) ||
( a == 22 && b == 32 ) ||
( a == 22 && b == 35 ) ||
( a == 22 && b == 39 ) ||
( a == 23 && b == 25 ) ||
( a == 23 && b == 26 ) ||
( a == 23 && b == 33 ) ||
( a == 23 && b == 37 ) ||
( a == 24 && b == 25 ) ||
( a == 24 && b == 33 ) ||
( a == 24 && b == 38 ) ||
( a == 24 && b == 41 ) ||
( a == 25 && b == 27 ) ||
( a == 25 && b == 39 ) ||
( a == 25 && b == 43 ) ||
( a == 26 && b == 27 ) ||
( a == 26 && b == 28 ) ||
( a == 26 && b == 40 ) ||
( a == 27 && b == 30 ) ||
( a == 27 && b == 34 ) ||
( a == 28 && b == 29 ) ||
( a == 28 && b == 33 ) ||
( a == 28 && b == 34 ) ||
( a == 28 && b == 41 ) ||
( a == 29 && b == 31 ) ||
( a == 29 && b == 35 ) ||
( a == 29 && b == 36 ) ||
( a == 30 && b == 31 ) ||
( a == 30 && b == 35 ) ||
( a == 30 && b == 39 ) ||
( a == 30 && b == 40 ) ||
( a == 31 && b == 41 ) ||
( a == 31 && b == 42 ) ||
( a == 32 && b == 33 ) ||
( a == 32 && b == 34 ) ||
( a == 32 && b == 42 ) ||
( a == 33 && b == 36 ) ||
( a == 34 && b == 35 ) ||
( a == 34 && b == 43 ) ||
( a == 35 && b == 37 ) ||
( a == 36 && b == 37 ) ||
( a == 36 && b == 38 ) ||
( a == 36 && b == 42 ) ||
( a == 37 && b == 40 ) ||
( a == 37 && b == 43 ) ||
( a == 38 && b == 39 ) ||
( a == 38 && b == 40 ) ||
( a == 39 && b == 42 ) ||
( a == 40 && b == 41 ) ||
( a == 41 && b == 43 ) ||
( a == 42 && b == 43 ) )
return -(-4 + 7*Nc2 - 4*Nc4 + Nc6)/(32.*Nc3);
if( ( a == 20 && b == 23 ) ||
( a == 20 && b == 24 ) ||
( a == 20 && b == 28 ) ||
( a == 20 && b == 32 ) ||
( a == 20 && b == 36 ) ||
( a == 21 && b == 22 ) ||
( a == 21 && b == 25 ) ||
( a == 21 && b == 30 ) ||
( a == 21 && b == 38 ) ||
( a == 21 && b == 42 ) ||
( a == 22 && b == 25 ) ||
( a == 22 && b == 26 ) ||
( a == 22 && b == 30 ) ||
( a == 22 && b == 34 ) ||
( a == 23 && b == 24 ) ||
( a == 23 && b == 36 ) ||
( a == 23 && b == 39 ) ||
( a == 23 && b == 40 ) ||
( a == 24 && b == 27 ) ||
( a == 24 && b == 28 ) ||
( a == 24 && b == 40 ) ||
( a == 25 && b == 33 ) ||
( a == 25 && b == 34 ) ||
( a == 25 && b == 42 ) ||
( a == 26 && b == 29 ) ||
( a == 26 && b == 30 ) ||
( a == 26 && b == 34 ) ||
( a == 26 && b == 37 ) ||
( a == 27 && b == 28 ) ||
( a == 27 && b == 31 ) ||
( a == 27 && b == 40 ) ||
( a == 27 && b == 43 ) ||
( a == 28 && b == 31 ) ||
( a == 28 && b == 32 ) ||
( a == 29 && b == 30 ) ||
( a == 29 && b == 37 ) ||
( a == 29 && b == 38 ) ||
( a == 29 && b == 41 ) ||
( a == 30 && b == 38 ) ||
( a == 31 && b == 32 ) ||
( a == 31 && b == 35 ) ||
( a == 31 && b == 43 ) ||
( a == 32 && b == 35 ) ||
( a == 32 && b == 36 ) ||
( a == 33 && b == 34 ) ||
( a == 33 && b == 37 ) ||
( a == 33 && b == 41 ) ||
( a == 33 && b == 42 ) ||
( a == 34 && b == 37 ) ||
( a == 35 && b == 36 ) ||
( a == 35 && b == 39 ) ||
( a == 35 && b == 43 ) ||
( a == 36 && b == 39 ) ||
( a == 37 && b == 41 ) ||
( a == 38 && b == 41 ) ||
( a == 38 && b == 42 ) ||
( a == 39 && b == 40 ) ||
( a == 39 && b == 43 ) ||
( a == 40 && b == 43 ) ||
( a == 41 && b == 42 ) )
return (2 - 3*Nc2 + Nc4)/(16.*Nc3);
if( ( a == 20 && b == 25 ) ||
( a == 20 && b == 34 ) ||
( a == 20 && b == 37 ) ||
( a == 20 && b == 41 ) ||
( a == 20 && b == 42 ) ||
( a == 21 && b == 23 ) ||
( a == 21 && b == 35 ) ||
( a == 21 && b == 36 ) ||
( a == 21 && b == 40 ) ||
( a == 21 && b == 43 ) ||
( a == 22 && b == 24 ) ||
( a == 22 && b == 28 ) ||
( a == 22 && b == 31 ) ||
( a == 22 && b == 40 ) ||
( a == 22 && b == 43 ) ||
( a == 23 && b == 29 ) ||
( a == 23 && b == 30 ) ||
( a == 23 && b == 41 ) ||
( a == 23 && b == 42 ) ||
( a == 24 && b == 29 ) ||
( a == 24 && b == 30 ) ||
( a == 24 && b == 34 ) ||
( a == 24 && b == 37 ) ||
( a == 25 && b == 28 ) ||
( a == 25 && b == 31 ) ||
( a == 25 && b == 35 ) ||
( a == 25 && b == 36 ) ||
( a == 26 && b == 31 ) ||
( a == 26 && b == 32 ) ||
( a == 26 && b == 36 ) ||
( a == 26 && b == 39 ) ||
( a == 26 && b == 43 ) ||
( a == 27 && b == 29 ) ||
( a == 27 && b == 33 ) ||
( a == 27 && b == 37 ) ||
( a == 27 && b == 38 ) ||
( a == 27 && b == 42 ) ||
( a == 28 && b == 30 ) ||
( a == 28 && b == 38 ) ||
( a == 28 && b == 42 ) ||
( a == 29 && b == 39 ) ||
( a == 29 && b == 43 ) ||
( a == 30 && b == 32 ) ||
( a == 30 && b == 36 ) ||
( a == 31 && b == 33 ) ||
( a == 31 && b == 37 ) ||
( a == 32 && b == 37 ) ||
( a == 32 && b == 38 ) ||
( a == 32 && b == 41 ) ||
( a == 33 && b == 35 ) ||
( a == 33 && b == 39 ) ||
( a == 33 && b == 40 ) ||
( a == 34 && b == 36 ) ||
( a == 34 && b == 39 ) ||
( a == 34 && b == 40 ) ||
( a == 35 && b == 38 ) ||
( a == 35 && b == 41 ) ||
( a == 38 && b == 43 ) ||
( a == 39 && b == 41 ) ||
( a == 40 && b == 42 ) )
return (4 - 3*Nc2 - 2*Nc4 + Nc6)/(32.*Nc3);
if( ( a == 20 && b == 27 ) ||
( a == 20 && b == 31 ) ||
( a == 20 && b == 35 ) ||
( a == 20 && b == 39 ) ||
( a == 20 && b == 40 ) ||
( a == 21 && b == 26 ) ||
( a == 21 && b == 29 ) ||
( a == 21 && b == 33 ) ||
( a == 21 && b == 34 ) ||
( a == 21 && b == 41 ) ||
( a == 22 && b == 29 ) ||
( a == 22 && b == 33 ) ||
( a == 22 && b == 37 ) ||
( a == 22 && b == 38 ) ||
( a == 22 && b == 42 ) ||
( a == 23 && b == 27 ) ||
( a == 23 && b == 28 ) ||
( a == 23 && b == 32 ) ||
( a == 23 && b == 35 ) ||
( a == 23 && b == 43 ) ||
( a == 24 && b == 31 ) ||
( a == 24 && b == 32 ) ||
( a == 24 && b == 36 ) ||
( a == 24 && b == 39 ) ||
( a == 24 && b == 43 ) ||
( a == 25 && b == 26 ) ||
( a == 25 && b == 30 ) ||
( a == 25 && b == 37 ) ||
( a == 25 && b == 38 ) ||
( a == 25 && b == 41 ) ||
( a == 26 && b == 33 ) ||
( a == 26 && b == 38 ) ||
( a == 26 && b == 41 ) ||
( a == 27 && b == 32 ) ||
( a == 27 && b == 35 ) ||
( a == 27 && b == 39 ) ||
( a == 28 && b == 35 ) ||
( a == 28 && b == 36 ) ||
( a == 28 && b == 40 ) ||
( a == 28 && b == 43 ) ||
( a == 29 && b == 33 ) ||
( a == 29 && b == 34 ) ||
( a == 29 && b == 42 ) ||
( a == 30 && b == 34 ) ||
( a == 30 && b == 37 ) ||
( a == 30 && b == 41 ) ||
( a == 30 && b == 42 ) ||
( a == 31 && b == 36 ) ||
( a == 31 && b == 39 ) ||
( a == 31 && b == 40 ) ||
( a == 32 && b == 39 ) ||
( a == 32 && b == 43 ) ||
( a == 33 && b == 38 ) ||
( a == 34 && b == 41 ) ||
( a == 34 && b == 42 ) ||
( a == 35 && b == 40 ) ||
( a == 36 && b == 40 ) ||
( a == 36 && b == 43 ) ||
( a == 37 && b == 38 ) ||
( a == 37 && b == 42 ) )
return -(-1 + Nc2)/(8.*Nc3);
if( ( a == 20 && b == 30 ) ||
( a == 20 && b == 33 ) ||
( a == 21 && b == 28 ) ||
( a == 21 && b == 39 ) ||
( a == 22 && b == 27 ) ||
( a == 22 && b == 36 ) ||
( a == 23 && b == 34 ) ||
( a == 23 && b == 38 ) ||
( a == 24 && b == 26 ) ||
( a == 24 && b == 42 ) ||
( a == 25 && b == 32 ) ||
( a == 25 && b == 40 ) ||
( a == 26 && b == 35 ) ||
( a == 27 && b == 41 ) ||
( a == 28 && b == 37 ) ||
( a == 29 && b == 32 ) ||
( a == 29 && b == 40 ) ||
( a == 30 && b == 43 ) ||
( a == 31 && b == 34 ) ||
( a == 31 && b == 38 ) ||
( a == 33 && b == 43 ) ||
( a == 35 && b == 42 ) ||
( a == 36 && b == 41 ) ||
( a == 37 && b == 39 ) )
return (4 - 5*Nc2 + Nc4)/(32.*Nc3);
if( ( a == 20 && b == 43 ) ||
( a == 21 && b == 37 ) ||
( a == 22 && b == 41 ) ||
( a == 23 && b == 31 ) ||
( a == 24 && b == 35 ) ||
( a == 25 && b == 29 ) ||
( a == 26 && b == 42 ) ||
( a == 27 && b == 36 ) ||
( a == 28 && b == 39 ) ||
( a == 30 && b == 33 ) ||
( a == 32 && b == 40 ) ||
( a == 34 && b == 38 ) )
return -(-1 + Nc4)/(8.*Nc3);
}
if ( basis == id33bar888 ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) )
return (2 - 3*Nc2 + Nc4)/8.;
if( a == 0 && b == 1 )
return (1 - Nc2)/4.;
if( ( a == 0 && b == 2 ) ||
( a == 0 && b == 3 ) ||
( a == 0 && b == 4 ) ||
( a == 1 && b == 2 ) ||
( a == 1 && b == 3 ) ||
( a == 1 && b == 4 ) )
return 0;
if( ( a == 0 && b == 5 ) ||
( a == 0 && b == 8 ) ||
( a == 0 && b == 9 ) ||
( a == 1 && b == 6 ) ||
( a == 1 && b == 7 ) ||
( a == 1 && b == 10 ) )
return (2 - 3*Nc2 + Nc4)/(8.*Nc);
if( ( a == 0 && b == 6 ) ||
( a == 0 && b == 7 ) ||
( a == 0 && b == 10 ) ||
( a == 1 && b == 5 ) ||
( a == 1 && b == 8 ) ||
( a == 1 && b == 9 ) )
return -(-1 + Nc2)/(4.*Nc);
if( ( a == 2 && b == 2 ) ||
( a == 3 && b == 3 ) ||
( a == 4 && b == 4 ) )
return sqr(-1 + Nc2)/8.;
if( ( a == 2 && b == 3 ) ||
( a == 2 && b == 4 ) ||
( a == 3 && b == 4 ) )
return (-1 + Nc2)/8.;
if( ( a == 2 && b == 5 ) ||
( a == 2 && b == 6 ) ||
( a == 2 && b == 8 ) ||
( a == 2 && b == 10 ) ||
( a == 3 && b == 6 ) ||
( a == 3 && b == 7 ) ||
( a == 3 && b == 8 ) ||
( a == 3 && b == 9 ) ||
( a == 4 && b == 5 ) ||
( a == 4 && b == 7 ) ||
( a == 4 && b == 9 ) ||
( a == 4 && b == 10 ) )
return sqr(-1 + Nc2)/(8.*Nc);
if( ( a == 2 && b == 7 ) ||
( a == 2 && b == 9 ) ||
( a == 3 && b == 5 ) ||
( a == 3 && b == 10 ) ||
( a == 4 && b == 6 ) ||
( a == 4 && b == 8 ) )
return -(-1 + Nc2)/(8.*Nc);
if( ( a == 5 && b == 5 ) ||
( a == 6 && b == 6 ) ||
( a == 7 && b == 7 ) ||
( a == 8 && b == 8 ) ||
( a == 9 && b == 9 ) ||
( a == 10 && b == 10 ) )
return pow(-1 + Nc2,3.)/(8.*Nc2);
if( ( a == 5 && b == 6 ) ||
( a == 5 && b == 7 ) ||
( a == 6 && b == 9 ) ||
( a == 7 && b == 8 ) ||
( a == 8 && b == 10 ) ||
( a == 9 && b == 10 ) )
return -sqr(-1 + Nc2)/(8.*Nc2);
if( ( a == 5 && b == 8 ) ||
( a == 5 && b == 9 ) ||
( a == 6 && b == 7 ) ||
( a == 6 && b == 10 ) ||
( a == 7 && b == 10 ) ||
( a == 8 && b == 9 ) )
return 0.125 - 1/(8.*Nc2);
if( ( a == 5 && b == 10 ) ||
( a == 6 && b == 8 ) ||
( a == 7 && b == 9 ) )
return (-1 + Nc4)/(8.*Nc2);
}
if ( basis == id33bar33bar8 ) {
if( ( a == 0 && b == 0 ) ||
( a == 1 && b == 1 ) ||
( a == 2 && b == 2 ) ||
( a == 3 && b == 3 ) )
return (Nc*(-1 + Nc2))/2.;
if( ( a == 0 && b == 1 ) ||
( a == 0 && b == 3 ) ||
( a == 1 && b == 2 ) ||
( a == 2 && b == 3 ) )
return (-1 + Nc2)/2.;
if( ( a == 0 && b == 2 ) ||
( a == 1 && b == 3 ) )
return 0;
}
} else {
if ( a != b )
return 0.;
if ( basis == id88 ) {
return Nc2/4.;
}
if ( basis == id33bar ) {
return Nc;
}
if ( basis == id888 ) {
return Nc3/8.;
}
if ( basis == id33bar8 ) {
return Nc2/2.;
}
if ( basis == id8888 ) {
return Nc4/16.;
}
if ( basis == id33bar88 ) {
return Nc3/4.;
}
if ( basis == id33bar33bar ) {
return Nc2;
}
if ( basis == id88888 ) {
return Nc5/32.;
}
if ( basis == id33bar888 ) {
return Nc4/8.;
}
if ( basis == id33bar33bar8 ) {
return Nc3/2.;
}
}
throw Exception() << "SimpleColourBasis2::scalarProduct(): Cannot handle colour configuration" << Exception::runerror;
}
double SimpleColourBasis2::tMatrixElement(size_t i, size_t a,
size_t b,
const vector<PDT::Colour>&,
const vector<PDT::Colour>& basis,
#ifndef NDEBUG
size_t k, size_t l,
#else
size_t , size_t ,
#endif
const map<size_t,size_t>& dict) const {
// Check indices k and l
assert( k == i );
assert( l == basis.size() );
// Check that dict is the standardMap
assert( dict.size()+1 == basis.size() );
map<size_t,size_t>::const_iterator tmp;
for ( size_t ii = 0; ii < basis.size(); ii++ )
if ( ii != i ) {
tmp = dict.find(ii);
assert( tmp != dict.end() );
assert( tmp->second == ii );
}
if ( id33bar.empty() )
makeIds();
if ( basis == id88 ) {
if(i == 0 && a == 0 && b == 0) return -1;
if(i == 0 && a == 1 && b == 0) return 1;
if(i == 1 && a == 0 && b == 0) return 1;
if(i == 1 && a == 1 && b == 0) return -1;
return 0.;
}
if ( basis == id33bar ) {
if(i == 0 && a == 0 && b == 0) return 1;
if(i == 1 && a == 0 && b == 0) return -1;
return 0.;
}
if ( basis == id888 ) {
if(i == 0 && a == 3 && b == 0) return -1;
if(i == 0 && a == 5 && b == 1) return -1;
if(i == 0 && a == 7 && b == 0) return 1;
if(i == 0 && a == 8 && b == 1) return 1;
if(i == 1 && a == 4 && b == 0) return 1;
if(i == 1 && a == 5 && b == 1) return 1;
if(i == 1 && a == 6 && b == 1) return -1;
if(i == 1 && a == 7 && b == 0) return -1;
if(i == 2 && a == 3 && b == 0) return 1;
if(i == 2 && a == 4 && b == 0) return -1;
if(i == 2 && a == 6 && b == 1) return 1;
if(i == 2 && a == 8 && b == 1) return -1;
return 0.;
}
if ( basis == id33bar8 ) {
if(i == 0 && a == 2 && b == 0) return 1;
if(i == 1 && a == 1 && b == 0) return -1;
if(i == 2 && a == 1 && b == 0) return 1;
if(i == 2 && a == 2 && b == 0) return -1;
return 0.;
}
if ( basis == id8888 ) {
if(i == 0 && a == 2 && b == 2) return -1;
if(i == 0 && a == 5 && b == 1) return -1;
if(i == 0 && a == 8 && b == 0) return -1;
if(i == 0 && a == 9 && b == 2) return 1;
if(i == 0 && a == 10 && b == 1) return 1;
if(i == 0 && a == 11 && b == 0) return 1;
if(i == 0 && a == 20 && b == 3) return -1;
if(i == 0 && a == 22 && b == 4) return -1;
if(i == 0 && a == 26 && b == 5) return -1;
if(i == 0 && a == 28 && b == 6) return -1;
if(i == 0 && a == 32 && b == 7) return -1;
if(i == 0 && a == 34 && b == 8) return -1;
if(i == 0 && a == 38 && b == 3) return 1;
if(i == 0 && a == 39 && b == 4) return 1;
if(i == 0 && a == 40 && b == 5) return 1;
if(i == 0 && a == 41 && b == 6) return 1;
if(i == 0 && a == 42 && b == 7) return 1;
if(i == 0 && a == 43 && b == 8) return 1;
if(i == 1 && a == 2 && b == 2) return 1;
if(i == 1 && a == 9 && b == 2) return -1;
if(i == 1 && a == 13 && b == 0) return -1;
if(i == 1 && a == 15 && b == 1) return -1;
if(i == 1 && a == 16 && b == 0) return 1;
if(i == 1 && a == 17 && b == 1) return 1;
if(i == 1 && a == 24 && b == 3) return 1;
if(i == 1 && a == 25 && b == 4) return 1;
if(i == 1 && a == 27 && b == 5) return 1;
if(i == 1 && a == 28 && b == 6) return 1;
if(i == 1 && a == 29 && b == 6) return -1;
if(i == 1 && a == 30 && b == 5) return -1;
if(i == 1 && a == 33 && b == 7) return 1;
if(i == 1 && a == 34 && b == 8) return 1;
if(i == 1 && a == 35 && b == 8) return -1;
if(i == 1 && a == 36 && b == 7) return -1;
if(i == 1 && a == 38 && b == 3) return -1;
if(i == 1 && a == 39 && b == 4) return -1;
if(i == 2 && a == 5 && b == 1) return 1;
if(i == 2 && a == 10 && b == 1) return -1;
if(i == 2 && a == 13 && b == 0) return 1;
if(i == 2 && a == 16 && b == 0) return -1;
if(i == 2 && a == 18 && b == 2) return -1;
if(i == 2 && a == 19 && b == 2) return 1;
if(i == 2 && a == 21 && b == 3) return 1;
if(i == 2 && a == 22 && b == 4) return 1;
if(i == 2 && a == 23 && b == 4) return -1;
if(i == 2 && a == 24 && b == 3) return -1;
if(i == 2 && a == 30 && b == 5) return 1;
if(i == 2 && a == 31 && b == 6) return 1;
if(i == 2 && a == 32 && b == 7) return 1;
if(i == 2 && a == 33 && b == 7) return -1;
if(i == 2 && a == 35 && b == 8) return 1;
if(i == 2 && a == 37 && b == 8) return -1;
if(i == 2 && a == 40 && b == 5) return -1;
if(i == 2 && a == 41 && b == 6) return -1;
if(i == 3 && a == 8 && b == 0) return 1;
if(i == 3 && a == 11 && b == 0) return -1;
if(i == 3 && a == 15 && b == 1) return 1;
if(i == 3 && a == 17 && b == 1) return -1;
if(i == 3 && a == 18 && b == 2) return 1;
if(i == 3 && a == 19 && b == 2) return -1;
if(i == 3 && a == 20 && b == 3) return 1;
if(i == 3 && a == 21 && b == 3) return -1;
if(i == 3 && a == 23 && b == 4) return 1;
if(i == 3 && a == 25 && b == 4) return -1;
if(i == 3 && a == 26 && b == 5) return 1;
if(i == 3 && a == 27 && b == 5) return -1;
if(i == 3 && a == 29 && b == 6) return 1;
if(i == 3 && a == 31 && b == 6) return -1;
if(i == 3 && a == 36 && b == 7) return 1;
if(i == 3 && a == 37 && b == 8) return 1;
if(i == 3 && a == 42 && b == 7) return -1;
if(i == 3 && a == 43 && b == 8) return -1;
return 0.;
}
if ( basis == id33bar88 ) {
if(i == 0 && a == 4 && b == 0) return 1;
if(i == 0 && a == 9 && b == 1) return 1;
if(i == 0 && a == 10 && b == 2) return 1;
if(i == 1 && a == 4 && b == 0) return -1;
if(i == 1 && a == 5 && b == 1) return -1;
if(i == 1 && a == 7 && b == 2) return -1;
if(i == 2 && a == 0 && b == 0) return -1;
if(i == 2 && a == 1 && b == 0) return 1;
if(i == 2 && a == 6 && b == 1) return 1;
if(i == 2 && a == 7 && b == 2) return 1;
if(i == 2 && a == 8 && b == 2) return -1;
if(i == 2 && a == 9 && b == 1) return -1;
if(i == 3 && a == 0 && b == 0) return 1;
if(i == 3 && a == 1 && b == 0) return -1;
if(i == 3 && a == 5 && b == 1) return 1;
if(i == 3 && a == 6 && b == 1) return -1;
if(i == 3 && a == 8 && b == 2) return 1;
if(i == 3 && a == 10 && b == 2) return -1;
return 0.;
}
if ( basis == id33bar33bar ) {
if(i == 0 && a == 0 && b == 0) return 1;
if(i == 0 && a == 1 && b == 1) return 1;
if(i == 1 && a == 1 && b == 1) return -1;
if(i == 1 && a == 2 && b == 0) return -1;
if(i == 2 && a == 2 && b == 0) return 1;
if(i == 2 && a == 3 && b == 1) return 1;
if(i == 3 && a == 0 && b == 0) return -1;
if(i == 3 && a == 3 && b == 1) return -1;
return 0.;
}
throw Exception() << "SimpleColourBasis2::tMatrixElement(): Cannot handle colour configuration" << Exception::runerror;
return 0.;
}
bool SimpleColourBasis2::colourConnected(const cPDVector& sub,
const vector<PDT::Colour>& basis,
const pair<int,bool>& i,
const pair<int,bool>& j,
size_t a) const {
if ( id33bar.empty() )
makeIds();
// translate process to basis ids
map<cPDVector,map<size_t,size_t> >::const_iterator trans
= indexMap().find(sub);
assert(trans != indexMap().end());
int idColoured = i.second ? j.first : i.first;
idColoured = trans->second.find(idColoured)->second;
int idAntiColoured = i.second ? i.first : j.first;
idAntiColoured = trans->second.find(idAntiColoured)->second;
if ( basis == id88 ) {
return
a == 0 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0));
}
if ( basis == id33bar ) {
return
a == 0 &&
(idColoured == 0 && idAntiColoured == 1);
}
if ( basis == id888 ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0)));
}
if ( basis == id33bar8 ) {
return
a == 0 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1));
}
if ( basis == id8888 ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 2 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2))) ||
(a == 3 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 4 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 5 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 6 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 7 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 8 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0)));
}
if ( basis == id33bar88 ) {
return
(a == 0 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3))) ||
(a == 2 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 3 && idAntiColoured == 2)));
}
if ( basis == id33bar33bar ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3)));
}
if ( basis == id88888 ) {
return
(a == 0 &&
((idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 1 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 2 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 3 &&
((idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 4 &&
((idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 5 &&
((idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 6 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 7 &&
((idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 8 &&
((idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 9 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 10 &&
((idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 11 &&
((idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 12 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 13 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 14 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 15 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 16 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 17 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 18 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2))) ||
(a == 19 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2))) ||
(a == 20 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 21 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 22 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 23 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 24 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 25 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 26 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 27 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 28 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 29 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 30 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 31 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 32 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 33 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 34 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 0))) ||
(a == 35 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 36 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 37 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 38 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 39 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 40 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 0))) ||
(a == 41 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0))) ||
(a == 42 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 0))) ||
(a == 43 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 1 && idAntiColoured == 0)));
}
if ( basis == id33bar888 ) {
return
(a == 0 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 1))) ||
(a == 2 &&
((idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 3 &&
((idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 1))) ||
(a == 4 &&
((idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 5 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 4))) ||
(a == 6 &&
((idColoured == 0 && idAntiColoured == 2) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3))) ||
(a == 7 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 3 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 4))) ||
(a == 8 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 3 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 2))) ||
(a == 9 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 3 && idAntiColoured == 1) ||
(idColoured == 4 && idAntiColoured == 2) ||
(idColoured == 2 && idAntiColoured == 3))) ||
(a == 10 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 2 && idAntiColoured == 1) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 3 && idAntiColoured == 2)));
}
if ( basis == id33bar33bar8 ) {
return
(a == 0 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 1))) ||
(a == 1 &&
((idColoured == 0 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 3))) ||
(a == 2 &&
((idColoured == 0 && idAntiColoured == 3) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 1))) ||
(a == 3 &&
((idColoured == 0 && idAntiColoured == 1) ||
(idColoured == 2 && idAntiColoured == 4) ||
(idColoured == 4 && idAntiColoured == 3)));
}
throw Exception() << "SimpleColourBasis2::colourConnected(): Cannot handle colour configuration" << Exception::runerror;
return false;
}
map<size_t,vector<vector<size_t> > > SimpleColourBasis2::basisList(const vector<PDT::Colour>& basis) const {
if ( id33bar.empty() )
makeIds();
map<size_t,vector<vector<size_t> > > blist;
vector<vector<size_t> > structures;
vector<size_t> structure;
if ( basis == id88 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
return blist;
}
if ( basis == id33bar ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
return blist;
}
if ( basis == id888 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[1] = structures;
return blist;
}
if ( basis == id33bar8 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
return blist;
}
if ( basis == id8888 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[3] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[4] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[5] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[6] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[7] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[8] = structures;
return blist;
}
if ( basis == id33bar88 ) {
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[2] = structures;
return blist;
}
if ( basis == id33bar33bar ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
return blist;
}
if ( basis == id88888 ) {
structures.clear();
structure.clear();
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[3] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[4] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[5] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[6] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[7] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[8] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[9] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[10] = structures;
structures.clear();
structure.clear();
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[11] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[12] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[13] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[14] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[15] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[16] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structures.push_back(structure);
structure.clear();
structure.push_back(1);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[17] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[18] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[19] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[20] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[21] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[22] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(3);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[23] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(4);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[24] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structure.push_back(4);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[25] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
blist[26] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[27] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
blist[28] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[29] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[30] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[31] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
blist[32] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structure.push_back(4);
structure.push_back(2);
structures.push_back(structure);
blist[33] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structure.push_back(4);
structures.push_back(structure);
blist[34] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[35] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[36] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[37] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[38] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structure.push_back(3);
structure.push_back(2);
structures.push_back(structure);
blist[39] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structure.push_back(1);
structure.push_back(3);
structures.push_back(structure);
blist[40] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[41] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structure.push_back(1);
structure.push_back(2);
structures.push_back(structure);
blist[42] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[43] = structures;
return blist;
}
if ( basis == id33bar888 ) {
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(3);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(4);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[3] = structures;
structures.clear();
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[4] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(3);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[5] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[6] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[7] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structure.push_back(4);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[8] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(2);
structure.push_back(3);
structure.push_back(1);
structures.push_back(structure);
blist[9] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[10] = structures;
return blist;
}
if ( basis == id33bar33bar8 ) {
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(1);
structures.push_back(structure);
blist[0] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(3);
structures.push_back(structure);
blist[1] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(3);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(1);
structures.push_back(structure);
blist[2] = structures;
structures.clear();
structure.clear();
structure.push_back(0);
structure.push_back(1);
structures.push_back(structure);
structure.clear();
structure.push_back(2);
structure.push_back(4);
structure.push_back(3);
structures.push_back(structure);
blist[3] = structures;
return blist;
}
throw Exception() << "SimpleColourBasis2::basisList(): Cannot handle colour configuration" << Exception::runerror;
return blist;
}
void SimpleColourBasis2::makeIds() const {
id88 = vector<PDT::Colour>(2,PDT::Colour8);
id33bar.push_back(PDT::Colour3);
id33bar.push_back(PDT::Colour3bar);
id888 = vector<PDT::Colour>(3,PDT::Colour8);
id33bar8 = id33bar;
id33bar8.push_back(PDT::Colour8);
id8888 = vector<PDT::Colour>(4,PDT::Colour8);
id33bar88 = id33bar8;
id33bar88.push_back(PDT::Colour8);
id33bar33bar = id33bar;
id33bar33bar.push_back(PDT::Colour3);
id33bar33bar.push_back(PDT::Colour3bar);
id88888 = vector<PDT::Colour>(5,PDT::Colour8);
id33bar888 = id33bar88;
id33bar888.push_back(PDT::Colour8);
id33bar33bar8 = id33bar33bar;
id33bar33bar8.push_back(PDT::Colour8);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void SimpleColourBasis2::persistentOutput(PersistentOStream &) const {}
void SimpleColourBasis2::persistentInput(PersistentIStream &, int) {}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<SimpleColourBasis2,ColourBasis>
describeHerwigSimpleColourBasis2("Herwig::SimpleColourBasis2", "Herwig.so");
void SimpleColourBasis2::Init() {
static ClassDocumentation<SimpleColourBasis2> documentation
("SimpleColourBasis2 implements the colour algebra needed for "
"processes with four coloured legs at NLO. It mainly "
"serves as an example for the general ColourBasis interface.");
}
diff --git a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.h b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.h
--- a/MatrixElement/Matchbox/Utility/SimpleColourBasis2.h
+++ b/MatrixElement/Matchbox/Utility/SimpleColourBasis2.h
@@ -1,233 +1,218 @@
// -*- C++ -*-
//
// SimpleColourBasis2.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_SimpleColourBasis2_H
#define Herwig_SimpleColourBasis2_H
//
// This is the declaration of the SimpleColourBasis2 class.
//
#include "Herwig/MatrixElement/Matchbox/Utility/ColourBasis.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief SimpleColourBasis2 implements the colour algebra needed for
* processes with four coloured legs at NLO. It mainly serves as an
* example for the general ColourBasis interface.
*
*/
class SimpleColourBasis2: public ColourBasis {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- SimpleColourBasis2();
-
- /**
- * The destructor.
- */
- virtual ~SimpleColourBasis2();
- //@}
-
-public:
-
/**
* Prepare the basis for the normal ordered legs and return the
* dimensionality of the basis.
*/
virtual size_t prepareBasis(const vector<PDT::Colour>&);
/**
* Return the scalar product of basis tensors labelled a and b in
* the basis used for the given normal ordered legs.
*/
virtual double scalarProduct(size_t a, size_t b,
const vector<PDT::Colour>& abBasis) const;
/**
* Return the matrix element of a colour charge
* <c_{n+1,a}|T_i|c_{n,b}> between basis tensors a and b, with
* respect to aBasis and bBasis
*/
virtual double tMatrixElement(size_t i, size_t a, size_t b,
const vector<PDT::Colour>& aBasis,
const vector<PDT::Colour>& bBasis,
size_t k, size_t l,
const map<size_t,size_t>& dict) const;
/*
* Temporary to make it compile
*/
virtual double sMatrixElement(size_t, size_t, size_t,
const vector<PDT::Colour>&,
const vector<PDT::Colour>&,
size_t, size_t,
const map<size_t,size_t>&
) const {
assert( 0 == 1 );
return 0;
}
/**
* Return true, if this colour basis supports gluon splittings.
*/
virtual bool canSplitGluons() const {
return false;
}
/**
* Return true, if a large-N colour connection exists for the
* given external legs and basis tensor.
*/
virtual bool colourConnected(const cPDVector&,
const vector<PDT::Colour>&,
const pair<int,bool>&,
const pair<int,bool>&,
size_t) const;
/**
* Return true, if the colour basis is capable of assigning colour
* flows.
*/
virtual bool haveColourFlows() const { return true; }
/**
* Create ids for bases
*/
void makeIds() const;
/**
* Return a map of basis tensor indices to vectors identifying a
* certain ordering corresponding to the given colour structure. May
* not be supported by all colour basis implementations.
*/
virtual map<size_t,vector<vector<size_t> > > basisList(const vector<PDT::Colour>&) 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:
/**
* id for 88
*/
mutable vector<PDT::Colour> id88;
/**
* id for 33bar
*/
mutable vector<PDT::Colour> id33bar;
/**
* id for 888
*/
mutable vector<PDT::Colour> id888;
/**
* id for 33bar8
*/
mutable vector<PDT::Colour> id33bar8;
/**
* id for 8888
*/
mutable vector<PDT::Colour> id8888;
/**
* id for 33bar88
*/
mutable vector<PDT::Colour> id33bar88;
/**
* id for 33bar33bar
*/
mutable vector<PDT::Colour> id33bar33bar;
/**
* id for 88888
*/
mutable vector<PDT::Colour> id88888;
/**
* id for 33bar888
*/
mutable vector<PDT::Colour> id33bar888;
/**
* id for 33bar33bar8
*/
mutable vector<PDT::Colour> id33bar33bar8;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
SimpleColourBasis2 & operator=(const SimpleColourBasis2 &) = delete;
};
}
#endif /* Herwig_SimpleColourBasis2_H */
diff --git a/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc b/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc
--- a/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc
+++ b/MatrixElement/Matchbox/Utility/Tree2toNGenerator.cc
@@ -1,490 +1,488 @@
// -*- C++ -*-
//
// Tree2toNGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 Tree2toNGenerator class.
//
#include "Tree2toNGenerator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Utilities/StringUtils.h"
using namespace Herwig;
Tree2toNGenerator::Tree2toNGenerator()
: maxOrderGs(0), maxOrderGem(0), prepared(false) {}
-Tree2toNGenerator::~Tree2toNGenerator() {}
-
IBPtr Tree2toNGenerator::clone() const {
return new_ptr(*this);
}
IBPtr Tree2toNGenerator::fullclone() const {
return new_ptr(*this);
}
vector<Ptr<Tree2toNDiagram>::ptr> Tree2toNGenerator::
generate(const PDVector& legs,
unsigned int orderInGs,
unsigned int orderInGem) {
vector<Ptr<Tree2toNDiagram>::ptr> res;
list<vector<Vertex> > prog = clusterAll(legs,orderInGs,orderInGem);
int count = 1;
for ( auto & d : prog ) {
assert(d.size() == 1);
Tree2toNDiagram diag = d.front().generate(count);
if ( !spaceLikeAllowed.empty() ) {
map<tcPDPtr,int> counts;
for ( int k = 1; k < diag.nSpace()-1; ++k )
counts[diag.allPartons()[k]] += 1;
for ( auto & m : spaceLikeAllowed ) {
m.reset();
for ( auto const & c : counts )
m.add(c.first,c.second);
}
bool failed = false;
for ( auto const & m : spaceLikeAllowed) {
if ( !m.check() ) {
failed = true;
break;
}
}
if ( failed )
continue;
}
if ( !timeLikeAllowed.empty() ) {
map<tcPDPtr,int> counts;
int all = diag.allPartons().size();
for ( int k = diag.nSpace(); k < all; ++k ) {
if ( diag.children(k).first < 0 )
continue;
counts[diag.allPartons()[k]] += 1;
}
for ( auto & m : timeLikeAllowed ) {
m.reset();
for ( auto const & c : counts )
m.add(c.first,c.second);
}
bool failed = false;
for ( auto const & m : timeLikeAllowed ) {
if ( !m.check() ) {
failed = true;
break;
}
}
if ( failed )
continue;
}
bool internalVeto = false;
set<int> external;
int nex = diag.partons().size();
for ( int i = 0; i < nex; ++i ) {
external.insert(diag.diagramId(i));
}
int n = diag.allPartons().size();
for ( int i = 0; i < n; ++i ) {
if ( external.find(i) != external.end() )
continue;
if ( find(excludeInternal().begin(), excludeInternal().end(), diag.allPartons()[i])
!= excludeInternal().end() ) {
internalVeto = true;
break;
}
}
if ( internalVeto )
continue;
bool gotit = false;
for ( auto const & d : res) {
map<int,int> checkPermutation;
if ( diag.isSame(d,checkPermutation) ) {
gotit = true;
for ( auto const & p : checkPermutation )
if ( p.first != p.second )
gotit = false;
if ( gotit )
break;
}
}
if ( !gotit ) {
res.push_back(new_ptr(diag));
++count;
}
}
return res;
}
list<vector<Tree2toNGenerator::Vertex> > Tree2toNGenerator::
cluster(const vector<Tree2toNGenerator::Vertex>& children,
unsigned int orderInGs,
unsigned int orderInGem) const {
list<vector<Vertex> > res;
bool externalCluster = children[1].externalId != -1;
if ( children.size() == 3 ) {
for ( auto const & v : theVertices ) {
if ( v->getNpoint() != 3 )
continue;
if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) !=
theExcludeVertices.end() )
continue;
bool noMatch =
v->orderInGs() != int(orderInGs) ||
v->orderInGem() != int(orderInGem) ||
!v->isIncoming(children[0].parent);
long idij = children[0].parent->id();
long idi = children[2].parent->id();
long idj = children[1].parent->id();
if ( externalCluster && children[1].parent->CC() )
idj = -idj;
if ( children[0].parent->CC() )
idij = -idij;
if ( !externalCluster )
noMatch |=
!v->isOutgoing(children[1].parent) ||
!v->isOutgoing(children[2].parent);
else
noMatch |=
!v->isIncoming(children[1].parent) ||
!v->isOutgoing(children[2].parent);
noMatch |=
!( v->allowed(idij,idi,idj) ||
v->allowed(idj,idij,idi) ||
v->allowed(idi,idj,idij) ||
v->allowed(idij,idj,idi) ||
v->allowed(idi,idij,idj) ||
v->allowed(idj,idi,idij) );
if ( noMatch )
continue;
Vertex last;
last.spacelike = true;
last.parent = children[0].parent;
last.externalId = 0;
last.children.push_back(children[1]);
last.children.push_back(children[2]);
res.push_back(vector<Vertex>(1,last));
// only one possible
break;
}
return res;
}
// spacelike clusterings (cluster on second one)
for ( size_t i = 2; i < children.size(); ++i ) {
for ( auto const & v : theVertices ) {
if ( v->getNpoint() != 3 )
continue;
if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) !=
theExcludeVertices.end() )
continue;
bool noMatch = false;
noMatch |=
v->orderInGs() != int(orderInGs) ||
v->orderInGem() != int(orderInGem);
if ( !externalCluster )
noMatch |=
!v->isOutgoing(children[1].parent) ||
!v->isOutgoing(children[i].parent);
else
noMatch |=
!v->isIncoming(children[1].parent) ||
!v->isOutgoing(children[i].parent);
if ( noMatch )
continue;
long idi = children[i].parent->id();
long idj = children[1].parent->id();
if ( externalCluster && children[1].parent->CC() )
idj = -idj;
for ( set<tPDPtr>::const_iterator pij =
v->outgoing().begin(); pij != v->outgoing().end() ; ++pij ) {
long idij = (**pij).id();
if ( v->allowed(idij,idi,idj) ||
v->allowed(idj,idij,idi) ||
v->allowed(idi,idj,idij) ||
v->allowed(idij,idj,idi) ||
v->allowed(idi,idij,idj) ||
v->allowed(idj,idi,idij) ) {
PDPtr dij = (**pij).CC() ? (**pij).CC() : *pij;
vector<Vertex> cled;
for ( size_t k = 0; k < children.size(); ++k ) {
if ( k != 1 && k != i )
cled.push_back(children[k]);
if ( k == 1 ) {
Vertex merge;
merge.children.push_back(children[1]);
merge.children.push_back(children[i]);
merge.parent = dij;
merge.spacelike = true;
cled.push_back(merge);
}
if ( k == i )
continue;
}
res.push_back(cled);
}
}
}
}
// timelike clusterings
for ( size_t i = 2; i < children.size(); ++i ) {
for ( size_t j = i+1; j < children.size(); ++j ) {
for ( auto const & v : theVertices ) {
if ( v->getNpoint() != 3 )
continue;
if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) !=
theExcludeVertices.end() )
continue;
if ( v->orderInGs() != int(orderInGs) ||
v->orderInGem() != int(orderInGem) ||
!v->isOutgoing(children[i].parent) ||
!v->isOutgoing(children[j].parent) )
continue;
long idi = children[i].parent->id();
long idj = children[j].parent->id();
for ( set<tPDPtr>::const_iterator pij =
v->outgoing().begin(); pij != v->outgoing().end() ; ++pij ) {
long idij = (**pij).id();
if ( v->allowed(idij,idi,idj) ||
v->allowed(idj,idij,idi) ||
v->allowed(idi,idj,idij) ||
v->allowed(idij,idj,idi) ||
v->allowed(idi,idij,idj) ||
v->allowed(idj,idi,idij) ) {
PDPtr dij = (**pij).CC() ? (**pij).CC() : *pij;
vector<Vertex> cled;
for ( size_t k = 0; k < children.size(); ++k ) {
if ( k != i && k != j )
cled.push_back(children[k]);
if ( k == i ) {
Vertex merge;
merge.children.push_back(children[i]);
merge.children.push_back(children[j]);
merge.parent = dij;
merge.spacelike = false;
cled.push_back(merge);
}
if ( k == j )
continue;
}
res.push_back(cled);
}
}
}
}
}
return res;
}
list<vector<Tree2toNGenerator::Vertex> > Tree2toNGenerator::
clusterAll(const list<vector<Tree2toNGenerator::Vertex> >& current,
unsigned int orderInGs,
unsigned int orderInGem) const {
list<vector<Vertex> > res;
for ( list<vector<Vertex> >::const_iterator c = current.begin();
c != current.end(); ++c ) {
if ( c->size() == 1 ) {
if ( orderInGs == 0 && orderInGem == 0 )
res.push_back(*c);
continue;
}
for ( unsigned int gs = 0; gs <= maxOrderGs; ++gs )
for ( unsigned int gem = 0; gem <= maxOrderGem; ++gem ) {
if ( gs == 0 && gem == 0 )
continue;
if ( gs > orderInGs || gem > orderInGem )
continue;
list<vector<Vertex> > next = cluster(*c,gs,gem);
if ( next.empty() )
continue;
list<vector<Vertex> > cled = clusterAll(next,orderInGs-gs,orderInGem-gem);
copy(cled.begin(),cled.end(),back_inserter(res));
}
}
return res;
}
list<vector<Tree2toNGenerator::Vertex> > Tree2toNGenerator::
clusterAll(const PDVector& external,
unsigned int orderInGs,
unsigned int orderInGem) {
if ( !prepared ) {
for ( auto & v : theVertices ) {
if ( find(theExcludeVertices.begin(), theExcludeVertices.end(), v) !=
theExcludeVertices.end() )
continue;
v->init();
maxOrderGs = max(maxOrderGs,v->orderInGs());
maxOrderGem = max(maxOrderGem,v->orderInGem());
}
for ( auto & m : spaceLikeAllowed)
m.rebind(this);
for ( auto & m : timeLikeAllowed )
m.rebind(this);
prepared = true;
}
vector<Vertex> legs;
for ( unsigned int k = 0; k < external.size(); ++k ) {
Vertex v;
v.parent = external[k];
v.externalId = k;
v.spacelike = k < 2;
legs.push_back(v);
}
list<vector<Vertex> > firstlegs;
firstlegs.push_back(legs);
return clusterAll(firstlegs,orderInGs,orderInGem);
}
string Tree2toNGenerator::doSpaceLikeRange(string range) {
if ( theRestrictLines.empty() )
return "No particle data specified to restrict internal lines.";
vector<string> bounds = StringUtils::split(range);
if ( bounds.empty() || bounds.size() > 2 )
return "Need to specify a minimum, or a minimum and maximum number of internal lines.";
pair<int,int> irange(0,-1);
istringstream in1(bounds[0]);
in1 >> irange.first;
if ( bounds.size() == 2 ) {
istringstream in2(bounds[1]);
in2 >> irange.second;
} else {
irange.second = irange.first;
}
if ( irange.second >= 0 && irange.first > irange.second )
return "invalid range specified";
spaceLikeAllowed.push_back(LineMatcher(theRestrictLines,irange));
return "";
}
string Tree2toNGenerator::doTimeLikeRange(string range) {
if ( theRestrictLines.empty() )
return "No particle data specified to restrict internal lines.";
vector<string> bounds = StringUtils::split(range);
if ( bounds.empty() || bounds.size() > 2 )
return "Need to specify a minimum, or a minimum and maximum number of internal lines.";
pair<int,int> irange(0,-1);
istringstream in1(bounds[0]);
in1 >> irange.first;
if ( bounds.size() == 2 ) {
istringstream in2(bounds[1]);
in2 >> irange.second;
} else {
irange.second = irange.first;
}
if ( irange.second >= 0 && irange.first > irange.second )
return "invalid range specified";
timeLikeAllowed.push_back(LineMatcher(theRestrictLines,irange));
return "";
}
string Tree2toNGenerator::doClearRestrictLines(string) {
theRestrictLines.clear();
return "";
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void Tree2toNGenerator::persistentOutput(PersistentOStream & os) const {
os << theVertices << theExcludeInternal << maxOrderGs << maxOrderGem << prepared
<< theExcludeVertices << spaceLikeAllowed << timeLikeAllowed;
}
void Tree2toNGenerator::persistentInput(PersistentIStream & is, int) {
is >> theVertices >> theExcludeInternal >> maxOrderGs >> maxOrderGem >> prepared
>> theExcludeVertices >> spaceLikeAllowed >> timeLikeAllowed;
}
// *** 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<Tree2toNGenerator,HandlerBase>
describeHerwigTree2toNGenerator("Herwig::Tree2toNGenerator", "Herwig.so");
void Tree2toNGenerator::Init() {
static ClassDocumentation<Tree2toNGenerator> documentation
("Generate Tree2toNDiagrams for a given process.");
static RefVector<Tree2toNGenerator,Helicity::VertexBase> interfaceVertices
("Vertices",
"All vertices to consider.",
&Tree2toNGenerator::theVertices, -1, false, false, true, false, false);
static RefVector<Tree2toNGenerator,Helicity::VertexBase> interfaceExcludeVertices
("ExcludeVertices",
"The vertices to exclude.",
&Tree2toNGenerator::theExcludeVertices, -1, false, false, true, false, false);
static RefVector<Tree2toNGenerator,ParticleData> interfaceExcludeInternal
("ExcludeInternal",
"Particles to be exluded from becoming internal lines.",
&Tree2toNGenerator::theExcludeInternal, -1, false, false, true, false, false);
static RefVector<Tree2toNGenerator,ParticleData> interfaceRestrictLines
("RestrictLines",
"Particles to be exluded from becoming internal lines.",
&Tree2toNGenerator::theRestrictLines, -1, false, false, true, false, false);
static Command<Tree2toNGenerator> interfaceSpaceLikeRange
("SpaceLikeRange",
"Limit the number of spacelike occurences of the specified particle.",
&Tree2toNGenerator::doSpaceLikeRange, false);
static Command<Tree2toNGenerator> interfaceTimeLikeRange
("TimeLikeRange",
"Limit the number of timelike occurences of the specified particle.",
&Tree2toNGenerator::doTimeLikeRange, false);
static Command<Tree2toNGenerator> interfaceClearRestrictLines
("ClearRestrictLines",
"Clear the container of lines to be considered for restrictions.",
&Tree2toNGenerator::doClearRestrictLines, false);
}
diff --git a/MatrixElement/Matchbox/Utility/Tree2toNGenerator.h b/MatrixElement/Matchbox/Utility/Tree2toNGenerator.h
--- a/MatrixElement/Matchbox/Utility/Tree2toNGenerator.h
+++ b/MatrixElement/Matchbox/Utility/Tree2toNGenerator.h
@@ -1,438 +1,430 @@
// -*- C++ -*-
//
// Tree2toNGenerator.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_Tree2toNGenerator_H
#define Herwig_Tree2toNGenerator_H
//
// This is the declaration of the Tree2toNGenerator class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Helicity/Vertex/VertexBase.h"
#include "ThePEG/MatrixElement/Tree2toNDiagram.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief Generate Tree2toNDiagrams for a given process.
*
* @see \ref Tree2toNGeneratorInterfaces "The interfaces"
* defined for Tree2toNGenerator.
*/
class Tree2toNGenerator: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
Tree2toNGenerator();
- /**
- * The destructor.
- */
- virtual ~Tree2toNGenerator();
- //@}
-
public:
/**
* Generate all diagrams for the given process.
*/
vector<Ptr<Tree2toNDiagram>::ptr> generate(const PDVector&,
unsigned int orderInGs,
unsigned int orderInGem);
typedef vector<Ptr<Helicity::VertexBase>::ptr> VertexVector;
/**
* Access the vertices
*/
VertexVector& vertices() { return theVertices; }
/**
* Return the vertices
*/
const VertexVector& vertices() const { return theVertices; }
/**
* Access the particles to be excluded from internal lines
*/
PDVector& excludeInternal() { return theExcludeInternal; }
/**
* Return the particles to be excluded from internal lines
*/
const PDVector& excludeInternal() const { return theExcludeInternal; }
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();
public:
/**
* A node in internally used trees.
*/
struct Vertex {
/**
* The outgoing particles. If this is a spacelike node, the first
* child is considered the next spacelike (or second incoming)
* line. If children are empty, this is an external line.
*/
vector<Vertex> children;
/**
* The incoming line at this node.
*/
PDPtr parent;
/**
* True, if this is spacelike node.
*/
bool spacelike;
/**
* The external leg id.
*/
int externalId;
/**
* The parent diagram id.
*/
int parentId;
/**
* The default constructor.
*/
Vertex()
: spacelike(false), externalId(-1), parentId(-1) {}
/**
* Debug printout.
*/
void print(ostream& os, const string& prefix = "") const {
os << prefix << parent->PDGName()
<< "[" << (spacelike ? "s" : "t") << "] (";
if ( externalId < 0 )
os << "x)\n";
else
os << externalId << ")\n";
if ( !children.empty() ) {
os << prefix << "|__\n";
children[0].print(os,prefix + "| ");
os << prefix << "|__\n";
children[1].print(os,prefix + "| ");
}
}
/**
* Count the number of spacelike lines
*/
int nspace() const {
if ( children.empty() )
return 1;
int ret = 1;
ret += children[0].nspace();
return ret;
}
/**
* Update diagram returning a map of external ids to diagram id
* parents.
*/
void update(Tree2toNDiagram& diag,
map<int,pair<int,PDPtr> >& outgoing,
int& lastUsed) {
if ( externalId == 0 ) {
assert(lastUsed==0);
++lastUsed;
diag.operator,(parent);
children[0].parentId = lastUsed;
children[1].parentId = lastUsed;
children[0].update(diag,outgoing,lastUsed);
children[1].update(diag,outgoing,lastUsed);
for ( map<int,pair<int,PDPtr> >::iterator out =
outgoing.begin(); out != outgoing.end(); ++out ) {
diag.operator,(out->second.first);
diag.operator,(out->second.second);
}
return;
}
if ( spacelike ) {
++lastUsed;
diag.operator,(parent);
if ( externalId == 1 )
return;
children[0].parentId = lastUsed;
children[1].parentId = lastUsed;
children[0].update(diag,outgoing,lastUsed);
children[1].update(diag,outgoing,lastUsed);
return;
}
if ( children.empty() ) {
outgoing[externalId] =
make_pair(parentId,parent);
return;
}
diag.operator,(parentId);
diag.operator,(parent);
++lastUsed;
children[0].parentId = lastUsed;
children[1].parentId = lastUsed;
children[0].update(diag,outgoing,lastUsed);
children[1].update(diag,outgoing,lastUsed);
}
/**
* Generate a diagram of given id.
*/
Tree2toNDiagram generate(int id) {
int nsp = nspace();
Tree2toNDiagram res(nsp);
int diagid = 0;
map<int,pair<int,PDPtr> > out;
update(res,out,diagid);
res.operator,(-id);
return res;
}
};
/**
* For the given set of trees determine all allowed clusterings.
*/
list<vector<Vertex> > cluster(const vector<Vertex>& children,
unsigned int orderInGs,
unsigned int orderInGem) const;
/**
* For the given set of outgoing lines cluster recursively.
*/
list<vector<Vertex> > clusterAll(const list<vector<Vertex> >& current,
unsigned int orderInGs,
unsigned int orderInGem) const;
/**
* For the given set of outgoing lines cluster recursively.
*/
list<vector<Vertex> > clusterAll(const PDVector& external,
unsigned int orderInGs,
unsigned int orderInGem);
/**
* Helper for topology restrictions
*/
struct LineMatcher {
/**
* The group of lines to be considered
*/
set<tcPDPtr> particles;
/**
* The range allowed
*/
pair<int,int> range;
/**
* The current count
*/
int count;
/**
* Default constructor
*/
LineMatcher()
: range(0,0), count(0) {}
/**
* Construct given particles and a range
*/
LineMatcher(const PDVector& p,
const pair<int,int>& r)
: range(r), count(0) {
copy(p.begin(),p.end(),inserter(particles,particles.begin()));
}
/**
* Rebind the particle data pointers
*/
void rebind(Tree2toNGenerator* g) {
set<tcPDPtr> oldp = particles;
particles.clear();
for ( set<tcPDPtr>::const_iterator p = oldp.begin();
p != oldp.end(); ++p )
particles.insert(g->getParticleData((**p).id()));
}
/**
* Reset this matcher
*/
void reset() {
count = 0;
}
/**
* Count the given multiplicity
*/
void add(tcPDPtr p, int n) {
if ( particles.find(p) == particles.end() )
return;
count += n;
}
/**
* Ceck if restrictions are met
*/
bool check() const {
return
count >= range.first && count <= range.second;
}
};
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 vertices to be used.
*/
VertexVector theVertices;
/**
* The particles to be excluded from internal lines
*/
PDVector theExcludeInternal;
/**
* Maximum order in gs to consider.
*/
unsigned int maxOrderGs;
/**
* Maximum order in gem to consider.
*/
unsigned int maxOrderGem;
/**
* Wether or not the generator has been prepared
*/
bool prepared;
/**
* The vertices to be excluded.
*/
VertexVector theExcludeVertices;
/**
* Minimal and maximal occurences of spacelike internal lines
*/
vector<LineMatcher> spaceLikeAllowed;
/**
* Minimal and maximal occurences of timelike internal lines
*/
vector<LineMatcher> timeLikeAllowed;
/**
* The next particle for which internal lines need to be restricted
*/
PDVector theRestrictLines;
/**
* Command to set an allowed range of spacelike internal lines
*/
string doSpaceLikeRange(string);
/**
* Command to set an allowed range of timelike internal lines
*/
string doTimeLikeRange(string);
/**
* Command to clear the restrict lines container
*/
string doClearRestrictLines(string);
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
Tree2toNGenerator & operator=(const Tree2toNGenerator &) = delete;
};
inline PersistentOStream& operator<<(PersistentOStream& os, const Tree2toNGenerator::LineMatcher& m) {
os << m.particles << m.range << m.count;
return os;
}
inline PersistentIStream& operator>>(PersistentIStream& is, Tree2toNGenerator::LineMatcher& m) {
is >> m.particles >> m.range >> m.count;
return is;
}
}
#endif /* Herwig_Tree2toNGenerator_H */
diff --git a/MatrixElement/ProductionMatrixElement.h b/MatrixElement/ProductionMatrixElement.h
--- a/MatrixElement/ProductionMatrixElement.h
+++ b/MatrixElement/ProductionMatrixElement.h
@@ -1,419 +1,419 @@
// -*- C++ -*-
//
// ProductionMatrixElement.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_ProductionMatrixElement_H
#define HERWIG_ProductionMatrixElement_H
//
// This is the declaration of the ProductionMatrixElement class.
#include <ThePEG/EventRecord/RhoDMatrix.h>
namespace Herwig {
using namespace ThePEG;
/** \ingroup Helicity
*
* The storage of the helicity amplitude expression for the matrix element
* of a hard process. Two incoming particles and an arbitary number of
* external particles are supported.
*
* @see DecayMatrixElement
* @see RhoDMatrix
* @see HardVertex
*
* \author Peter Richardson
*/
class ProductionMatrixElement {
public:
/** @name Standard constructors and destructors. */
//@{
/**
* Constructor for 2-1 scattering.
* @param in1 \f$2S+1\f$ for the first incoming particle.
* @param in2 \f$2S+1\f$ for the second incoming particle.
* @param out \f$2S+1\f$ for the outgoing particle.
*/
ProductionMatrixElement(PDT::Spin in1,PDT::Spin in2,PDT::Spin out);
/**
* Constructor for 2-2 scattering.
* @param in1 \f$2S+1\f$ for the first incoming particle.
* @param in2 \f$2S+1\f$ for the second incoming particle.
* @param out1 \f$2S+1\f$ for the first outgoing particle.
* @param out2 \f$2S+1\f$ for the second outgoing particle.
*/
ProductionMatrixElement(PDT::Spin in1,PDT::Spin in2,PDT::Spin out1,
PDT::Spin out2);
/**
* Constructor for 2-3 scattering.
* @param in1 \f$2S+1\f$ for the first incoming particle.
* @param in2 \f$2S+1\f$ for the second incoming particle.
* @param out1 \f$2S+1\f$ for the first outgoing particle.
* @param out2 \f$2S+1\f$ for the second outgoing particle.
* @param out3 \f$2S+1\f$ for the third outgoing particle.
*/
ProductionMatrixElement(PDT::Spin in1,PDT::Spin in2,PDT::Spin out1,
PDT::Spin out2,PDT::Spin out3);
/**
* Constructor for 2-4 scattering.
* @param in1 \f$2S+1\f$ for the first incoming particle.
* @param in2 \f$2S+1\f$ for the second incoming particle.
* @param out1 \f$2S+1\f$ for the first outgoing particle.
* @param out2 \f$2S+1\f$ for the second outgoing particle.
* @param out3 \f$2S+1\f$ for the third outgoing particle.
* @param out4 \f$2S+1\f$ for the fourth outgoing particle.
*/
ProductionMatrixElement(PDT::Spin in1,PDT::Spin in2,PDT::Spin out1,
PDT::Spin out2,PDT::Spin out3, PDT::Spin out4);
/**
* Constructor for 2-5 scattering.
* @param in1 \f$2S+1\f$ for the first incoming particle.
* @param in2 \f$2S+1\f$ for the second incoming particle.
* @param out1 \f$2S+1\f$ for the first outgoing particle.
* @param out2 \f$2S+1\f$ for the second outgoing particle.
* @param out3 \f$2S+1\f$ for the third outgoing particle.
* @param out4 \f$2S+1\f$ for the fourth outgoing particle.
* @param out5 \f$2S+1\f$ for the fifth outgoing particle.
*/
ProductionMatrixElement(PDT::Spin in1,PDT::Spin in2,PDT::Spin out1,
PDT::Spin out2,PDT::Spin out3, PDT::Spin out4,
PDT::Spin out5);
/**
* Constructor for 2-6 scattering.
* @param in1 \f$2S+1\f$ for the first incoming particle.
* @param in2 \f$2S+1\f$ for the second incoming particle.
* @param out1 \f$2S+1\f$ for the first outgoing particle.
* @param out2 \f$2S+1\f$ for the second outgoing particle.
* @param out3 \f$2S+1\f$ for the third outgoing particle.
* @param out4 \f$2S+1\f$ for the fourth outgoing particle.
* @param out5 \f$2S+1\f$ for the fifth outgoing particle.
* @param out6 \f$2S+1\f$ for the sixth outgoing particle.
*/
ProductionMatrixElement(PDT::Spin in1,PDT::Spin in2,PDT::Spin out1,
PDT::Spin out2,PDT::Spin out3, PDT::Spin out4,
PDT::Spin out5, PDT::Spin out6);
/**
* Constructor for 2-n scattering.
* @param in1 \f$2S+1\f$ for the first incoming particle.
* @param in2 \f$2S+1\f$ for the second incoming particle.
* @param out A vector containing \f$2S+1\f$ for the outgoing particles.
*/
ProductionMatrixElement(PDT::Spin in1,PDT::Spin in2,vector<PDT::Spin> out);
/**
* Default constructor.
*/
- ProductionMatrixElement() {}
+ ProductionMatrixElement() : _nout(0) {}
//@}
public:
/** @name Access to the spins of the particles. */
//@{
/**
* Get the spins of the incoming particles particle
* @return A vector containing \f$2S+1\f$ for the two incoming particles.
*/
vector<PDT::Spin> inspin() {return _inspin;}
/**
* Get the spins of the outgoing particles.
* @return A vector containing \f$2S+1\f$ for the outgoing particles.
*/
vector<PDT::Spin> outspin() {return _outspin;}
//@}
public:
/** @name Access to the individual helicity components. */
//@{
/**
* Access the helicity components for a 2-1 scattering. This method supplies
* the component but does not allow it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out The helicity of the outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex operator () (unsigned int in1,unsigned int in2,
unsigned int out) const;
/**
* Access the helicity components for a 2-1 scattering. This method supplies
* the component and allows it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out The helicity of the outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex & operator () (unsigned int in1,unsigned int in2,
unsigned int out);
/**
* Access the helicity components for a 2-2 scattering. This method supplies
* the component but does not allow it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out1 The helicity of the first outgoing particle.
* @param out2 The helicity of the second outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex operator () (unsigned int in1,unsigned int in2,
unsigned int out1,unsigned int out2) const;
/**
* Access the helicity components for a 2-2 scattering. This method supplies
* the component and allows it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out1 The helicity of the first outgoing particle.
* @param out2 The helicity of the second outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex & operator () (unsigned int in1,unsigned int in2,
unsigned int out1,unsigned int out2);
/**
* Access the helicity components for a 2-3 scattering. This method supplies
* the component but does not allow it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out1 The helicity of the first outgoing particle.
* @param out2 The helicity of the second outgoing particle.
* @param out3 The helicity of the third outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex operator () (unsigned int in1,unsigned int in2,
unsigned int out1,unsigned int out2,
unsigned int out3) const;
/**
* Access the helicity components for a 2-3 scattering. This method supplies
* the component and allows it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out1 The helicity of the first outgoing particle.
* @param out2 The helicity of the second outgoing particle.
* @param out3 The helicity of the third outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex & operator () (unsigned int in1,unsigned int in2,
unsigned int out1,unsigned int out2,
unsigned int out3);
/**
* Access the helicity components for a 2-4 scattering. This method supplies
* the component but does not allow it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out1 The helicity of the first outgoing particle.
* @param out2 The helicity of the second outgoing particle.
* @param out3 The helicity of the third outgoing particle.
* @param out4 The helicity of the fourth outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex operator () (unsigned int in1,unsigned int in2,
unsigned int out1,unsigned int out2,
unsigned int out3,unsigned int out4) const;
/**
* Access the helicity components for a 2-4 scattering. This method supplies
* the component and allows it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out1 The helicity of the first outgoing particle.
* @param out2 The helicity of the second outgoing particle.
* @param out3 The helicity of the third outgoing particle.
* @param out4 The helicity of the fourth outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex & operator () (unsigned int in1,unsigned int in2,
unsigned int out1,unsigned int out2,
unsigned int out3, unsigned int out4);
/**
* Access the helicity components for a 2-5 scattering. This method supplies
* the component but does not allow it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out1 The helicity of the first outgoing particle.
* @param out2 The helicity of the second outgoing particle.
* @param out3 The helicity of the third outgoing particle.
* @param out4 The helicity of the fourth outgoing particle.
* @param out5 The helicity of the fifth outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex operator () (unsigned int in1,unsigned int in2,
unsigned int out1,unsigned int out2,
unsigned int out3,unsigned int out4,
unsigned int out5) const;
/**
* Access the helicity components for a 2-5 scattering. This method supplies
* the component and allows it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out1 The helicity of the first outgoing particle.
* @param out2 The helicity of the second outgoing particle.
* @param out3 The helicity of the third outgoing particle.
* @param out4 The helicity of the fourth outgoing particle.
* @param out5 The helicity of the fifth outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex & operator () (unsigned int in1,unsigned int in2,
unsigned int out1,unsigned int out2,
unsigned int out3, unsigned int out4,
unsigned int out5);
/**
* Access the helicity components for a 2-6 scattering. This method supplies
* the component but does not allow it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out1 The helicity of the first outgoing particle.
* @param out2 The helicity of the second outgoing particle.
* @param out3 The helicity of the third outgoing particle.
* @param out4 The helicity of the fourth outgoing particle.
* @param out5 The helicity of the fifth outgoing particle.
* @param out6 The helicity of the sixth outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex operator () (unsigned int in1,unsigned int in2,
unsigned int out1,unsigned int out2,
unsigned int out3,unsigned int out4,
unsigned int out5,unsigned int out6) const;
/**
* Access the helicity components for a 2-6 scattering. This method supplies
* the component and allows it to be changed.
* @param in1 The helicity of the first incoming particle.
* @param in2 The helicity of the second incoming particle.
* @param out1 The helicity of the first outgoing particle.
* @param out2 The helicity of the second outgoing particle.
* @param out3 The helicity of the third outgoing particle.
* @param out4 The helicity of the fourth outgoing particle.
* @param out5 The helicity of the fifth outgoing particle.
* @param out6 The helicity of the sixth outgoing particle.
* @return The matrix element for the given helicities.
*/
Complex & operator () (unsigned int in1,unsigned int in2,
unsigned int out1,unsigned int out2,
unsigned int out3, unsigned int out4,
unsigned int out5, unsigned int out6);
/**
* Access the helicity components for a 2-n scattering. This method supplies
* the component but does not allow it to be changed.
* @param hel The helicities of the incoming and outgoing particles
* @return The matrix element for the given helicities.
*/
Complex operator () (vector<unsigned int> hel) const;
/**
* Access the helicity components for a 2-n scattering. This method supplies
* the component and allows it to be changed.
* @param hel The helicities of the incoming and outgoing particles
* @return The matrix element for the given helicities.
*/
Complex & operator () (vector<unsigned int> hel);
//@}
public:
/**
* Calculate the decay matrix for an incoming particle.
*/
RhoDMatrix calculateDMatrix(int,const RhoDMatrix &,
const vector<RhoDMatrix> &) const;
/**
* Calculate the rho matrix for a given outgoing particle.
*/
RhoDMatrix calculateRhoMatrix(int,const RhoDMatrix &,
const RhoDMatrix &,
const vector<RhoDMatrix> &) const;
/**
* Compute the spin averaged matrix element
*/
double average() const;
/**
* Compute the spin average matrix element
*/
double average(const RhoDMatrix & in1,
const RhoDMatrix & in2) const;
/**
* Compute the spin average matrix element
*/
Complex average(const ProductionMatrixElement & me2,
const RhoDMatrix & in1,
const RhoDMatrix & in2) const;
public:
/**
* Reset the matrix element.
*/
void reset(const ProductionMatrixElement & x) const;
/**
* Standard Init function used to initialize the interfaces.
*/
static void Init();
private:
/**
* Set the size of the vector containing the matrix element.
*/
void setMESize();
private:
/**
* Number of outgoing particles.
*/
mutable unsigned int _nout;
/**
* Spin of the incoming particles as 2s+1.
*/
mutable vector<PDT::Spin> _inspin;
/**
* Spins of the outgoing particles.
*/
mutable vector<PDT::Spin> _outspin;
/**
* Storage of the matrix element, a vector is better for memory usage.
*/
mutable vector<Complex> _matrixelement;
/**
* Constants needed to map the index of the vector to a helicity structure.
*/
mutable vector<int> _constants;
};
}
#endif /* HERWIG_ProductionMatrixElement_H */
diff --git a/Models/General/FourBodyDecayConstructor.cc b/Models/General/FourBodyDecayConstructor.cc
--- a/Models/General/FourBodyDecayConstructor.cc
+++ b/Models/General/FourBodyDecayConstructor.cc
@@ -1,259 +1,257 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FourBodyDecayConstructor class.
//
#include "FourBodyDecayConstructor.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/PDT/DecayMode.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/Models/StandardModel/StandardModel.h"
#include "Herwig/Decay/General/GeneralFourBodyDecayer.h"
#include "DecayConstructor.h"
using namespace Herwig;
-FourBodyDecayConstructor::~FourBodyDecayConstructor() {}
-
IBPtr FourBodyDecayConstructor::clone() const {
return new_ptr(*this);
}
IBPtr FourBodyDecayConstructor::fullclone() const {
return new_ptr(*this);
}
void FourBodyDecayConstructor::persistentOutput(PersistentOStream & os) const {
os << interOpt_ << widthOpt_ << particles_;
}
void FourBodyDecayConstructor::persistentInput(PersistentIStream & is, int) {
is >> interOpt_ >> widthOpt_ >> particles_;
}
DescribeClass<FourBodyDecayConstructor,NBodyDecayConstructorBase>
describeFourBodyDecayConstructor("Herwig::FourBodyDecayConstructor","Herwig.so");
void FourBodyDecayConstructor::Init() {
static ClassDocumentation<FourBodyDecayConstructor> documentation
("The FourBodyDecayConstructor class implements a small number"
" of 4-body decays in general models");
static Switch<FourBodyDecayConstructor,unsigned int> interfaceWidthOption
("WidthOption",
"Option for the treatment of the widths of the intermediates",
&FourBodyDecayConstructor::widthOpt_, 1, false, false);
static SwitchOption interfaceWidthOptionFixed
(interfaceWidthOption,
"Fixed",
"Use fixed widths",
1);
static SwitchOption interfaceWidthOptionRunning
(interfaceWidthOption,
"Running",
"Use running widths",
2);
static SwitchOption interfaceWidthOptionZero
(interfaceWidthOption,
"Zero",
"Set the widths to zero",
3);
static Switch<FourBodyDecayConstructor,unsigned int> interfaceIntermediateOption
("IntermediateOption",
"Option for the inclusion of intermediates in the event",
&FourBodyDecayConstructor::interOpt_, 0, false, false);
static SwitchOption interfaceIntermediateOptionAlways
(interfaceIntermediateOption,
"Always",
"Always include the intermediates",
1);
static SwitchOption interfaceIntermediateOptionNever
(interfaceIntermediateOption,
"Never",
"Never include the intermediates",
2);
static SwitchOption interfaceIntermediateOptionOnlyIfOnShell
(interfaceIntermediateOption,
"OnlyIfOnShell",
"Only if there are on-shell diagrams",
0);
static RefVector<FourBodyDecayConstructor,ParticleData> interfaceParticles
("Particles",
"Particles to override the choice in the DecayConstructor for 4-body decays,"
" if empty the defaults from the DecayConstructor are used.",
&FourBodyDecayConstructor::particles_, -1, false, false, true, true, false);
static Switch<FourBodyDecayConstructor,bool> interfaceParticleType
("ParticleType",
"Which types of particles to calculate four body decay modes for",
&FourBodyDecayConstructor::particleType_, false, false, false);
static SwitchOption interfaceParticleTypeStable
(interfaceParticleType,
"Stable",
"Only calculate four-body decays in no 2/3 body modes",
false);
static SwitchOption interfaceParticleTypeAll
(interfaceParticleType,
"All",
"Calculate 4-body modes for all particles",
true);
}
void FourBodyDecayConstructor::DecayList(const set<PDPtr,MassOrdering> & particles) {
if( particles.empty() ) return;
set<PDPtr,MassOrdering> new_particles;
for(set<PDPtr,MassOrdering>::const_iterator it=particles.begin();it!=particles.end();++it) {
if(!particles_.empty() && find(particles_.begin(),particles_.end(),*it)==particles_.end()) continue;
if(!(**it).stable()&&!particleType_) continue;
new_particles.insert(*it);
}
if(!new_particles.empty())
NBodyDecayConstructorBase::DecayList(new_particles);
}
void FourBodyDecayConstructor::
createDecayMode(vector<NBDiagram> & diagrams,
bool possibleOnShell, double symfac) {
// some basic checks for the modes we are interested in
// only looking at scalars
if(diagrams[0].incoming->iSpin()!=PDT::Spin0) return;
// which decay to 4 fermions
unsigned int nferm=0;
for(OrderedParticles::const_iterator it=diagrams[0].outgoing.begin();
it!=diagrams[0].outgoing.end();++it) {
if((**it).iSpin()==PDT::Spin1Half) ++nferm;
}
if(nferm!=4) return;
// check for on-shell intermediates
bool inter = interOpt_ == 1 || (interOpt_ == 0 && possibleOnShell);
// incoming particle
tPDPtr inpart = diagrams[0].incoming;
// outgoing particles
OrderedParticles outgoing=diagrams[0].outgoing;
// incoming particle is now unstable
inpart->stable(false);
// construct the tag for the decay mode
string tag = inpart->name() + "->";
for(OrderedParticles::const_iterator it = outgoing.begin();
it != outgoing.end(); ++it) {
if(it!=outgoing.begin()) tag += ",";
tag += (**it).name();
}
tag += ";";
tDMPtr dm = generator()->findDecayMode(tag);
// create mode if needed
if( createDecayModes() && (!dm || inpart->id() == ParticleID::h0) ) {
// create the decayer
GeneralFourBodyDecayerPtr decayer = createDecayer(diagrams,inter,symfac);
if(!decayer) {
if(Debug::level > 1 ) generator()->log() << "Can't create the decayer for "
<< tag << " so mode not created\n";
return;
}
// create the decay mode
tDMPtr ndm = generator()->preinitCreateDecayMode(tag);
if(ndm) {
string test = generator()->preinitInterface(ndm, "Decayer", "set",
decayer->fullName());
generator()->preinitInterface(ndm, "Active", "set", "Yes");
Energy width =
decayer->partialWidth(inpart,outgoing);
setBranchingRatio(ndm, width);
}
else
throw NBodyDecayConstructorError()
<< "FourBodyDecayConstructor::createDecayMode - Needed to create "
<< "new decaymode but one could not be created for the tag "
<< tag << Exception::warning;
}
// otherwise
else if (dm && (dm->decayer()->fullName()).find("Mambo") != string::npos) {
// create the decayer
GeneralFourBodyDecayerPtr decayer = createDecayer(diagrams,inter,symfac);
if(!decayer) {
if(Debug::level > 1 ) generator()->log() << "Can't create the decayer for "
<< tag << " so mode not created\n";
return;
}
generator()->preinitInterface(dm, "Decayer", "set",
decayer->fullName());
}
//update CC mode if it exists
if( inpart->CC() )
inpart->CC()->synchronize();
}
GeneralFourBodyDecayerPtr
FourBodyDecayConstructor::createDecayer(vector<NBDiagram> & diagrams,
bool inter, double symfac) const {
if(diagrams.empty()) return GeneralFourBodyDecayerPtr();
// extract the external particles for the process
PDPtr incoming = diagrams[0].incoming;
// outgoing particles
vector<PDPtr> outgoing(diagrams[0].outgoing.begin(),
diagrams[0].outgoing.end());
// get the name for the object
string objectname ("/Herwig/Decays/");
string classname = DecayerClassName(incoming, diagrams[0].outgoing, objectname);
if(classname=="") return GeneralFourBodyDecayerPtr();
// create the object
GeneralFourBodyDecayerPtr decayer =
dynamic_ptr_cast<GeneralFourBodyDecayerPtr>
(generator()->preinitCreate(classname, objectname));
// set up the decayer and return if doesn't work
if(!decayer->setDecayInfo(incoming,outgoing,diagrams,symfac))
return GeneralFourBodyDecayerPtr();
// set decayer options from base class
setDecayerInterfaces(objectname);
// set the width option
ostringstream value;
value << widthOpt_;
generator()->preinitInterface(objectname, "WidthOption", "set", value.str());
// set the intermediates option
ostringstream value2;
value2 << inter;
generator()->preinitInterface(objectname, "GenerateIntermediates", "set",
value2.str());
// initialize the decayer
decayer->init();
// return the decayer
return decayer;
}
string FourBodyDecayConstructor::DecayerClassName(tcPDPtr incoming,
const OrderedParticles & outgoing,
string & objname) const {
string classname("Herwig::");
// spins of the outgoing particles
unsigned int ns(0),nf(0),nv(0);
objname += incoming->PDGName() + "2";
for(OrderedParticles::const_iterator it=outgoing.begin();
it!=outgoing.end();++it) {
if ((**it).iSpin()==PDT::Spin0 ) ++ns;
else if((**it).iSpin()==PDT::Spin1Half) ++nf;
else if((**it).iSpin()==PDT::Spin1 ) ++nv;
objname += (**it).PDGName();
}
objname += "Decayer";
if(incoming->iSpin()==PDT::Spin0) {
if(nf==4) classname += "StoFFFFDecayer";
else classname = "";
}
else {
classname="";
}
return classname;
}
diff --git a/Models/General/FourBodyDecayConstructor.h b/Models/General/FourBodyDecayConstructor.h
--- a/Models/General/FourBodyDecayConstructor.h
+++ b/Models/General/FourBodyDecayConstructor.h
@@ -1,150 +1,145 @@
// -*- C++ -*-
#ifndef THEPEG_FourBodyDecayConstructor_H
#define THEPEG_FourBodyDecayConstructor_H
//
// This is the declaration of the FourBodyDecayConstructor class.
//
#include "NBodyDecayConstructorBase.h"
#include "ThePEG/Helicity/Vertex/VertexBase.h"
#include "Herwig/Decay/General/GeneralFourBodyDecayer.fh"
#include "PrototypeVertex.h"
namespace Herwig {
using namespace ThePEG;
using Helicity::VertexBasePtr;
/**
* Here is the documentation of the FourBodyDecayConstructor class.
*
* @see \ref FourBodyDecayConstructorInterfaces "The interfaces"
* defined for FourBodyDecayConstructor.
*/
class FourBodyDecayConstructor: public NBodyDecayConstructorBase {
public:
/**
* The default constructor.
*/
FourBodyDecayConstructor() :
interOpt_(0), widthOpt_(1), particleType_(false) {}
/**
- * Destructor
- */
- ~FourBodyDecayConstructor();
-
- /**
* Function used to determine allowed decaymodes, to be implemented
* in derived class.
* @param particles vector of ParticleData pointers containing
* particles in model
*/
virtual void DecayList(const set<PDPtr,MassOrdering> & particles);
/**
* Number of outgoing lines. Required for correct ordering.
*/
virtual unsigned int numBodies() const {return 4;}
/**
* Create a decay mode
*/
void createDecayMode(vector<NBDiagram> &,bool,double);
/**
* Create the decayer
* @param diagrams The diagrams for the decay
* @param inter Option for intermediates
*/
GeneralFourBodyDecayerPtr createDecayer(vector<NBDiagram> & diagrams,
bool inter, double symfac) const;
/**
* Contruct the classname and object name for the Decayer
* @param incoming The incoming particle
* @param outgoing The decay products
* @param objname a string containing the default path of the Decayer object
*/
string DecayerClassName(tcPDPtr incoming, const OrderedParticles & outgoing,
string & objname) const;
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FourBodyDecayConstructor & operator=(const FourBodyDecayConstructor &) = delete;
private:
/**
* Option for the inclusion of intermediates
*/
unsigned int interOpt_;
/**
* How to treat the widths of the intermediate particles
*/
unsigned int widthOpt_;
/**
* Particles to override the default list
*/
vector<PDPtr> particles_;
/**
* Types of particles
*/
bool particleType_;
};
}
#endif /* THEPEG_FourBodyDecayConstructor_H */
diff --git a/Models/General/HardProcessConstructor.cc b/Models/General/HardProcessConstructor.cc
--- a/Models/General/HardProcessConstructor.cc
+++ b/Models/General/HardProcessConstructor.cc
@@ -1,958 +1,958 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the HardProcessConstructor class.
//
#include "HardProcessConstructor.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
void HardProcessConstructor::persistentOutput(PersistentOStream & os) const {
os << debug_ << subProcess_ << model_;
}
void HardProcessConstructor::persistentInput(PersistentIStream & is, int) {
is >> debug_ >> subProcess_ >> model_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeAbstractClass<HardProcessConstructor,Interfaced>
describeHerwigHardProcessConstructor("Herwig::HardProcessConstructor", "Herwig.so");
void HardProcessConstructor::Init() {
static ClassDocumentation<HardProcessConstructor> documentation
("Base class for implementation of the automatic generation of hard processes");
static Switch<HardProcessConstructor,bool> interfaceDebugME
("DebugME",
"Print comparison with analytical ME",
&HardProcessConstructor::debug_, false, false, false);
static SwitchOption interfaceDebugMEYes
(interfaceDebugME,
"Yes",
"Print the debug information",
true);
static SwitchOption interfaceDebugMENo
(interfaceDebugME,
"No",
"Do not print the debug information",
false);
}
void HardProcessConstructor::doinit() {
Interfaced::doinit();
EGPtr eg = generator();
model_ = dynamic_ptr_cast<HwSMPtr>(eg->standardModel());
if(!model_)
throw InitException() << "HardProcessConstructor:: doinit() - "
<< "The model pointer is null!"
<< Exception::abortnow;
if(!eg->eventHandler()) {
throw
InitException() << "HardProcessConstructor:: doinit() - "
<< "The eventHandler pointer was null therefore "
<< "could not get SubProcessHandler pointer "
<< Exception::abortnow;
}
string subProcessName =
eg->preinitInterface(eg->eventHandler(), "SubProcessHandlers", "get","");
subProcess_ = eg->getObject<SubProcessHandler>(subProcessName);
if(!subProcess_) {
ostringstream s;
s << "HardProcessConstructor:: doinit() - "
<< "There was an error getting the SubProcessHandler "
<< "from the current event handler. ";
generator()->logWarning( Exception(s.str(), Exception::warning) );
}
}
GeneralHardME::ColourStructure HardProcessConstructor::
colourFlow(const tcPDVector & extpart) const {
PDT::Colour ina = extpart[0]->iColour();
PDT::Colour inb = extpart[1]->iColour();
PDT::Colour outa = extpart[2]->iColour();
PDT::Colour outb = extpart[3]->iColour();
// incoming colour neutral
if(ina == PDT::Colour0 && inb == PDT::Colour0) {
if( outa == PDT::Colour0 && outb == PDT::Colour0 ) {
return GeneralHardME::Colour11to11;
}
else if( outa == PDT::Colour3 && outb == PDT::Colour3bar ) {
return GeneralHardME::Colour11to33bar;
}
else if( outa == PDT::Colour8 && outb == PDT::Colour8 ) {
return GeneralHardME::Colour11to88;
}
else
assert(false);
}
// incoming 3 3
else if(ina == PDT::Colour3 && inb == PDT::Colour3 ) {
if( outa == PDT::Colour3 && outb == PDT::Colour3 ) {
return GeneralHardME::Colour33to33;
}
else if( outa == PDT::Colour6 && outb == PDT::Colour0 ) {
return GeneralHardME::Colour33to61;
}
else if( outa == PDT::Colour0 && outb == PDT::Colour6 ) {
return GeneralHardME::Colour33to16;
}
else if ( outa == PDT::Colour0 && outb == PDT::Colour3bar) {
return GeneralHardME::Colour33to13bar;
}
else if ( outb == PDT::Colour0 && outa == PDT::Colour3bar) {
return GeneralHardME::Colour33to3bar1;
}
else if ( outa == PDT::Colour8 && outb == PDT::Colour3bar) {
return GeneralHardME::Colour33to83bar;
}
else if ( outb == PDT::Colour8 && outa == PDT::Colour3bar) {
return GeneralHardME::Colour33to3bar8;
}
else
assert(false);
}
// incoming 3bar 3bar
else if(ina == PDT::Colour3bar && inb == PDT::Colour3bar ) {
if( outa == PDT::Colour3bar && outb == PDT::Colour3bar ) {
return GeneralHardME::Colour3bar3barto3bar3bar;
}
else if( outa == PDT::Colour6bar && outb == PDT::Colour0) {
return GeneralHardME::Colour3bar3barto6bar1;
}
else if ( outa == PDT::Colour0 && outb == PDT::Colour6bar ) {
return GeneralHardME::Colour3bar3barto16bar;
}
else if ( outa == PDT::Colour0 && outb == PDT::Colour3) {
return GeneralHardME::Colour3bar3barto13;
}
else if ( outb == PDT::Colour0 && outa == PDT::Colour3) {
return GeneralHardME::Colour3bar3barto31;
}
else if ( outa == PDT::Colour8 && outb == PDT::Colour3) {
return GeneralHardME::Colour3bar3barto83;
}
else if ( outb == PDT::Colour8 && outa == PDT::Colour3) {
return GeneralHardME::Colour3bar3barto38;
}
else
assert(false);
}
// incoming 3 3bar
else if(ina == PDT::Colour3 && inb == PDT::Colour3bar ) {
if( outa == PDT::Colour0 && outb == PDT::Colour0 ) {
return GeneralHardME::Colour33barto11;
}
else if( outa == PDT::Colour3 && outb == PDT::Colour3bar ) {
return GeneralHardME::Colour33barto33bar;
}
else if( outa == PDT::Colour8 && outb == PDT::Colour8 ) {
return GeneralHardME::Colour33barto88;
}
else if( outa == PDT::Colour8 && outb == PDT::Colour0 ) {
return GeneralHardME::Colour33barto81;
}
else if( outa == PDT::Colour0 && outb == PDT::Colour8 ) {
return GeneralHardME::Colour33barto18;
}
else if( outa == PDT::Colour6 && outb == PDT::Colour6bar) {
return GeneralHardME::Colour33barto66bar;
}
else if( outa == PDT::Colour6bar && outb == PDT::Colour6) {
return GeneralHardME::Colour33barto6bar6;
}
else
assert(false);
}
// incoming 88
else if(ina == PDT::Colour8 && inb == PDT::Colour8 ) {
if( outa == PDT::Colour0 && outb == PDT::Colour0 ) {
return GeneralHardME::Colour88to11;
}
else if( outa == PDT::Colour3 && outb == PDT::Colour3bar ) {
return GeneralHardME::Colour88to33bar;
}
else if( outa == PDT::Colour8 && outb == PDT::Colour8 ) {
return GeneralHardME::Colour88to88;
}
else if( outa == PDT::Colour8 && outb == PDT::Colour0 ) {
return GeneralHardME::Colour88to81;
}
else if( outa == PDT::Colour0 && outb == PDT::Colour8 ) {
return GeneralHardME::Colour88to18;
}
else if( outa == PDT::Colour6 && outb == PDT::Colour6bar ) {
return GeneralHardME::Colour88to66bar;
}
else
assert(false);
}
// incoming 38
else if(ina == PDT::Colour3 && inb == PDT::Colour8 ) {
if(outa == PDT::Colour3 && outb == PDT::Colour0) {
return GeneralHardME::Colour38to31;
}
else if(outa == PDT::Colour0 && outb == PDT::Colour3) {
return GeneralHardME::Colour38to13;
}
else if(outa == PDT::Colour3 && outb == PDT::Colour8) {
return GeneralHardME::Colour38to38;
}
else if(outa == PDT::Colour8 && outb == PDT::Colour3) {
return GeneralHardME::Colour38to83;
}
else if(outa == PDT::Colour3bar && outb == PDT::Colour6){
return GeneralHardME::Colour38to3bar6;
}
else if(outa == PDT::Colour6 && outb == PDT::Colour3bar) {
return GeneralHardME::Colour38to63bar;
}
else if(outa == PDT::Colour3bar && outb == PDT::Colour3bar) {
return GeneralHardME::Colour38to3bar3bar;
}
else
assert(false);
}
// incoming 3bar8
else if(ina == PDT::Colour3bar && inb == PDT::Colour8 ) {
if(outa == PDT::Colour3bar && outb == PDT::Colour0 ) {
return GeneralHardME::Colour3bar8to3bar1;
}
else if(outa == PDT::Colour0 && outb == PDT::Colour3bar) {
return GeneralHardME::Colour3bar8to13bar;
}
else if(outa == PDT::Colour3bar && outb == PDT::Colour8 ) {
return GeneralHardME::Colour3bar8to3bar8;
}
else if(outa == PDT::Colour8 && outb == PDT::Colour3bar) {
return GeneralHardME::Colour3bar8to83bar;
}
else if(outa == PDT::Colour3 && outb == PDT::Colour3) {
return GeneralHardME::Colour3bar8to33;
}
else
assert(false);
}
// unknown colour flow
else
assert(false);
return GeneralHardME::UNDEFINED;
}
void HardProcessConstructor::fixFSOrder(HPDiagram & diag) {
tcPDPtr psa = getParticleData(diag.incoming.first);
tcPDPtr psb = getParticleData(diag.incoming.second);
tcPDPtr psc = getParticleData(diag.outgoing.first);
tcPDPtr psd = getParticleData(diag.outgoing.second);
//fix a spin order
if( psc->iSpin() < psd->iSpin() ) {
swap(diag.outgoing.first, diag.outgoing.second);
if(diag.channelType == HPDiagram::tChannel) {
diag.ordered.second = !diag.ordered.second;
}
return;
}
if( psc->iSpin() == psd->iSpin() &&
psc->id() < 0 && psd->id() > 0 ) {
swap(diag.outgoing.first, diag.outgoing.second);
if(diag.channelType == HPDiagram::tChannel) {
diag.ordered.second = !diag.ordered.second;
}
return;
}
}
void HardProcessConstructor::assignToCF(HPDiagram & diag) {
if(diag.channelType == HPDiagram::tChannel) {
if(diag.ordered.second) tChannelCF(diag);
else uChannelCF(diag);
}
else if(diag.channelType == HPDiagram::sChannel) {
sChannelCF(diag);
}
else if (diag.channelType == HPDiagram::fourPoint) {
fourPointCF(diag);
}
else
assert(false);
}
void HardProcessConstructor::tChannelCF(HPDiagram & diag) {
tcPDPtr ia = getParticleData(diag.incoming.first );
tcPDPtr ib = getParticleData(diag.incoming.second);
tcPDPtr oa = getParticleData(diag.outgoing.first );
tcPDPtr ob = getParticleData(diag.outgoing.second);
PDT::Colour ina = ia->iColour();
PDT::Colour inb = ib->iColour();
PDT::Colour outa = oa->iColour();
PDT::Colour outb = ob->iColour();
vector<CFPair> cfv(1, make_pair(0, 1.));
if(diag.intermediate->iColour() == PDT::Colour0) {
if(ina==PDT::Colour0) {
cfv[0] = make_pair(0, 1);
}
else if(ina==PDT::Colour3 || ina==PDT::Colour3bar) {
if( inb == PDT::Colour0 ) {
cfv[0] = make_pair(0, 1);
}
else if(inb==PDT::Colour3 || outb==PDT::Colour3bar) {
cfv[0] = make_pair(2, 1);
}
else if(inb==PDT::Colour8) {
cfv[0] = make_pair(2, 1);
}
}
else if(ina==PDT::Colour8) {
if( inb == PDT::Colour0 ) {
cfv[0] = make_pair(0, 1);
}
else if(inb==PDT::Colour3 || outb==PDT::Colour3bar) {
cfv[0] = make_pair(2, 1);
}
else if(inb==PDT::Colour8) {
cfv[0] = make_pair(7, -1);
}
}
}
else if(diag.intermediate->iColour() == PDT::Colour8) {
if(ina==PDT::Colour8&&outa==PDT::Colour8&&
inb==PDT::Colour8&&outb==PDT::Colour8) {
cfv[0]=make_pair(2, 2.);
cfv.push_back(make_pair(3, -2.));
cfv.push_back(make_pair(1, -2.));
cfv.push_back(make_pair(4, 2.));
}
else if(ina==PDT::Colour8&&outa==PDT::Colour0&&
inb==PDT::Colour8&&outb==PDT::Colour8&&
(oa->iSpin()==PDT::Spin0||oa->iSpin()==PDT::Spin1Half||
oa->iSpin()==PDT::Spin3Half)) {
cfv[0] = make_pair(0,-1);
}
else if(ina==PDT::Colour8&&outa==PDT::Colour8&&
inb==PDT::Colour8&&outb==PDT::Colour0&&
(ob->iSpin()==PDT::Spin0||ob->iSpin()==PDT::Spin1Half||
ob->iSpin()==PDT::Spin3Half)) {
cfv[0] = make_pair(0,-1);
}
}
else if(diag.intermediate->iColour() == PDT::Colour3 ||
diag.intermediate->iColour() == PDT::Colour3bar) {
if(outa == PDT::Colour0 || outb == PDT::Colour0) {
if( outa == PDT::Colour6 || outb == PDT::Colour6 ||
outa == PDT::Colour6bar || outb == PDT::Colour6bar) {
cfv[0] = make_pair(0,0.5);
cfv.push_back(make_pair(1,0.5));
}
else if ((ina==PDT::Colour3 && inb == PDT::Colour3 &&
(outa == PDT::Colour3bar || outb == PDT::Colour3bar))||
(ina==PDT::Colour3bar && inb == PDT::Colour3bar &&
(outa == PDT::Colour3 || outb == PDT::Colour3 ))) {
cfv[0] = make_pair(0,1.);
}
else {
cfv[0] = make_pair(0,1.);
}
}
else if(outa==PDT::Colour6 && outb==PDT::Colour3bar) {
cfv[0] = make_pair(4,1.);
cfv.push_back(make_pair(5,1.));
}
else if(outa==PDT::Colour6 && outb==PDT::Colour6bar) {
cfv[0] = make_pair(4, 1.);
for(unsigned int ix=5;ix<8;++ix)
cfv.push_back(make_pair(ix,1.));
}
else if(outa==PDT::Colour6 || outa ==PDT::Colour6bar ||
outb==PDT::Colour6 || outb ==PDT::Colour6bar ) {
assert(false);
}
else if(ina==PDT::Colour3 && inb==PDT::Colour3 ) {
if((outa==PDT::Colour0 && outb==PDT::Colour3bar)||
(outb==PDT::Colour0 && outa==PDT::Colour3bar))
cfv[0] = make_pair(0,1.);
else if((outa==PDT::Colour8 && outb==PDT::Colour3bar)||
(outb==PDT::Colour8 && outa==PDT::Colour3bar)) {
cfv[0] = make_pair(1,1.);
}
}
else if(ina==PDT::Colour3bar && inb==PDT::Colour3bar ) {
if((outa==PDT::Colour0 && outb==PDT::Colour3)||
(outb==PDT::Colour0 && outa==PDT::Colour3))
cfv[0] = make_pair(0,1.);
else if((outa==PDT::Colour8 && outb==PDT::Colour3)||
(outb==PDT::Colour8 && outa==PDT::Colour3)) {
double sign = diag.intermediate->iSpin()==PDT::Spin0 ? -1. : 1.;
cfv[0] = make_pair(1,sign);
}
}
else if((ina==PDT::Colour3 && inb==PDT::Colour8) ||
(ina==PDT::Colour3bar && inb==PDT::Colour8) ||
(inb==PDT::Colour3 && ina==PDT::Colour8) ||
(inb==PDT::Colour3bar && ina==PDT::Colour8) ) {
if((outa==PDT::Colour3 && outb==PDT::Colour3 ) ||
(outa==PDT::Colour3bar && outb==PDT::Colour3bar)) {
cfv[0] = make_pair(1,1.);
}
}
}
else if(diag.intermediate->iColour() == PDT::Colour6 ||
diag.intermediate->iColour() == PDT::Colour6bar) {
if(ina==PDT::Colour8 && inb==PDT::Colour8) {
cfv[0] = make_pair(0, 1.);
for(unsigned int ix=1;ix<4;++ix)
cfv.push_back(make_pair(ix,1.));
for(unsigned int ix=4;ix<8;++ix)
cfv.push_back(make_pair(ix,1.));
}
else if(outa==PDT::Colour3bar && outb==PDT::Colour6) {
cfv[0] = make_pair(0,1.);
for(unsigned int ix=1;ix<4;++ix)
cfv.push_back(make_pair(ix,1.));
}
else if(outa==PDT::Colour6 && outb==PDT::Colour3bar) {
cfv[0] = make_pair(4,1.);
cfv.push_back(make_pair(5,1.));
}
}
diag.colourFlow = cfv;
}
void HardProcessConstructor::uChannelCF(HPDiagram & diag) {
tcPDPtr ia = getParticleData(diag.incoming.first );
tcPDPtr ib = getParticleData(diag.incoming.second);
tcPDPtr oa = getParticleData(diag.outgoing.first );
tcPDPtr ob = getParticleData(diag.outgoing.second);
PDT::Colour ina = ia->iColour();
PDT::Colour inb = ib->iColour();
PDT::Colour outa = oa->iColour();
PDT::Colour outb = ob->iColour();
PDT::Colour offshell = diag.intermediate->iColour();
vector<CFPair> cfv(1, make_pair(1, 1.));
if(offshell == PDT::Colour8) {
if(outa == PDT::Colour0 &&
outb == PDT::Colour0) {
cfv[0].first = 0;
}
else if( outa != outb ) {
if(outa == PDT::Colour0 ||
outb == PDT::Colour0) {
cfv[0].first = 0;
}
else if(ina == PDT::Colour3 && inb == PDT::Colour8 &&
outb == PDT::Colour3 && outa == PDT::Colour8) {
tPDPtr off = diag.intermediate;
if(off->CC()) off=off->CC();
if(off->iSpin()!=PDT::Spin1Half ||
diag.vertices.second->allowed(off->id(),diag.outgoing.first,diag.incoming.second)) {
cfv[0].first = 0;
cfv.push_back(make_pair(1, -1.));
}
else {
cfv[0].first = 1;
cfv.push_back(make_pair(0, -1.));
}
}
else if(ina == PDT::Colour3bar && inb == PDT::Colour8 &&
outb == PDT::Colour3bar && outa == PDT::Colour8) {
tPDPtr off = diag.intermediate;
if(off->CC()) off=off->CC();
if(off->iSpin()!=PDT::Spin1Half ||
diag.vertices.second->allowed(diag.outgoing.first,off->id(),diag.incoming.second)) {
cfv[0].first = 0;
cfv.push_back(make_pair(1, -1.));
}
else {
cfv[0].first = 1;
cfv.push_back(make_pair(0, -1.));
}
}
else {
cfv[0].first = 0;
cfv.push_back(make_pair(1, -1.));
}
}
else if(outa==PDT::Colour8&&ina==PDT::Colour8) {
cfv[0]=make_pair(4, 2.);
cfv.push_back(make_pair(5, -2.));
cfv.push_back(make_pair(0, -2.));
cfv.push_back(make_pair(2, 2.));
}
}
else if(offshell == PDT::Colour3 || offshell == PDT::Colour3bar) {
if( outa == PDT::Colour0 || outb == PDT::Colour0 ) {
if( outa == PDT::Colour6 || outb == PDT::Colour6 ||
outa == PDT::Colour6bar || outb == PDT::Colour6bar) {
cfv[0] = make_pair(0,0.5);
cfv.push_back(make_pair(1,0.5));
}
else if ((ina==PDT::Colour3 && inb == PDT::Colour3 &&
(outa == PDT::Colour3bar || outb == PDT::Colour3bar))||
(ina==PDT::Colour3bar && inb == PDT::Colour3bar &&
(outa == PDT::Colour3 || outb == PDT::Colour3 ))) {
double sign = diag.intermediate->iSpin()==PDT::Spin0 ? -1. : 1.;
cfv[0] = make_pair(0,sign);
}
else {
cfv[0] = make_pair(0,1.);
}
}
else if(outa==PDT::Colour3bar && outb==PDT::Colour6) {
cfv[0] = make_pair(4,1.);
cfv.push_back(make_pair(5,1.));
}
else if(outa==PDT::Colour6 && outb==PDT::Colour3bar) {
cfv[0] = make_pair(0,1.);
for(int ix=0; ix<4;++ix)
cfv.push_back(make_pair(ix,1.));
}
else if(outa==PDT::Colour6bar && outb==PDT::Colour6) {
cfv[0] = make_pair(4,1.);
for(int ix=5; ix<8;++ix)
cfv.push_back(make_pair(ix,1.));
}
else if(ina==PDT::Colour0 && inb==PDT::Colour0) {
cfv[0] = make_pair(0,1.);
}
else if(ina==PDT::Colour3 && inb==PDT::Colour3 ) {
if((outa==PDT::Colour0 && outb==PDT::Colour3bar)||
(outb==PDT::Colour0 && outa==PDT::Colour3bar))
cfv[0] = make_pair(0,1.);
else if((outa==PDT::Colour8 && outb==PDT::Colour3bar)||
(outb==PDT::Colour8 && outa==PDT::Colour3bar)) {
double sign = diag.intermediate->iSpin()==PDT::Spin0 ? -1. : 1.;
cfv[0] = make_pair(2,sign);
}
}
else if(ina==PDT::Colour3bar && inb==PDT::Colour3bar ) {
if((outa==PDT::Colour0 && outb==PDT::Colour3)||
(outb==PDT::Colour0 && outa==PDT::Colour3))
cfv[0] = make_pair(0,1.);
else if((outa==PDT::Colour8 && outb==PDT::Colour3)||
(outb==PDT::Colour8 && outa==PDT::Colour3)) {
cfv[0] = make_pair(2,1.);
}
}
else if(((ina==PDT::Colour3 && inb==PDT::Colour8) ||
(ina==PDT::Colour3bar && inb==PDT::Colour8) ||
(inb==PDT::Colour3 && ina==PDT::Colour8) ||
(inb==PDT::Colour3bar && ina==PDT::Colour8)) &&
((outa==PDT::Colour3 && outb==PDT::Colour3 ) ||
(outa==PDT::Colour3bar && outb==PDT::Colour3bar))) {
cfv[0] = make_pair(2, 1.);
}
else if(( ina==PDT::Colour3 && inb==PDT::Colour3bar &&
outa==PDT::Colour3 && outb==PDT::Colour3bar)) {
cfv[0] = make_pair(2, 1.);
cfv.push_back(make_pair(3,-1.));
}
}
else if( offshell == PDT::Colour0 ) {
if(ina==PDT::Colour0) {
cfv[0] = make_pair(0, 1);
}
else if(ina==PDT::Colour3 || ina==PDT::Colour3bar) {
if( inb == PDT::Colour0 ) {
cfv[0] = make_pair(0, 1);
}
else if(inb==PDT::Colour3 || inb==PDT::Colour3bar) {
cfv[0] = make_pair(3, 1);
}
else if(inb==PDT::Colour8) {
cfv[0] = make_pair(2, 1);
}
}
else if(ina==PDT::Colour8) {
if( inb == PDT::Colour0 ) {
cfv[0] = make_pair(0, 1);
}
else if(inb==PDT::Colour3 || outb==PDT::Colour3bar) {
cfv[0] = make_pair(2, 1);
}
else if(inb==PDT::Colour8) {
cfv[0] = make_pair(8, -1);
}
}
}
else if(diag.intermediate->iColour() == PDT::Colour6 ||
diag.intermediate->iColour() == PDT::Colour6bar) {
if(ina==PDT::Colour8 && inb==PDT::Colour8) {
cfv[0] = make_pair(0, 1.);
for(unsigned int ix=1;ix<4;++ix)
cfv.push_back(make_pair(ix,1.));
for(unsigned int ix=8;ix<12;++ix)
cfv.push_back(make_pair(ix,1.));
}
- else if(outa==PDT::Colour3bar && outa==PDT::Colour6) {
+ else if(outa==PDT::Colour3bar && outb==PDT::Colour6) {
cfv[0] = make_pair(4, 1.);
cfv.push_back(make_pair(5,1.));
}
- else if(outa==PDT::Colour6 && outa==PDT::Colour3bar) {
+ else if(outa==PDT::Colour6 && outb==PDT::Colour3bar) {
cfv[0] = make_pair(0, 1.);
for(unsigned int ix=1;ix<4;++ix)
cfv.push_back(make_pair(ix,1.));
}
}
diag.colourFlow = cfv;
}
void HardProcessConstructor::sChannelCF(HPDiagram & diag) {
tcPDPtr pa = getParticleData(diag.incoming.first);
tcPDPtr pb = getParticleData(diag.incoming.second);
PDT::Colour ina = pa->iColour();
PDT::Colour inb = pb->iColour();
PDT::Colour offshell = diag.intermediate->iColour();
tcPDPtr pc = getParticleData(diag.outgoing.first);
tcPDPtr pd = getParticleData(diag.outgoing.second);
PDT::Colour outa = pc->iColour();
PDT::Colour outb = pd->iColour();
vector<CFPair> cfv(1);
if(offshell == PDT::Colour8) {
if(ina == PDT::Colour0 || inb == PDT::Colour0 ||
outa == PDT::Colour0 || outb == PDT::Colour0) {
cfv[0] = make_pair(0, 1);
}
else {
bool incol = ina == PDT::Colour8 && inb == PDT::Colour8;
bool outcol = outa == PDT::Colour8 && outb == PDT::Colour8;
bool intrip = ina == PDT::Colour3 && inb == PDT::Colour3bar;
bool outtrip = outa == PDT::Colour3 && outb == PDT::Colour3bar;
bool outsex = outa == PDT::Colour6 && outb == PDT::Colour6bar;
bool outsexb = outa == PDT::Colour6bar && outb == PDT::Colour6;
if(incol || outcol) {
// Require an additional minus sign for a scalar/fermion
// 33bar final state due to the way the vertex rules are defined.
int prefact(1);
if( ((pc->iSpin() == PDT::Spin1Half && pd->iSpin() == PDT::Spin1Half) ||
(pc->iSpin() == PDT::Spin0 && pd->iSpin() == PDT::Spin0 ) ||
(pc->iSpin() == PDT::Spin1 && pd->iSpin() == PDT::Spin1 )) &&
(outa == PDT::Colour3 && outb == PDT::Colour3bar) )
prefact = -1;
if(incol && outcol) {
cfv[0] = make_pair(0, -2.);
cfv.push_back(make_pair(1, 2.));
cfv.push_back(make_pair(3, 2.));
cfv.push_back(make_pair(5, -2.));
}
else if(incol && outsex) {
cfv[0].first = 4;
cfv[0].second = prefact;
for(unsigned int ix=1;ix<4;++ix)
cfv.push_back(make_pair(4+ix, prefact));
for(unsigned int ix=0;ix<4;++ix)
cfv.push_back(make_pair(8+ix,-prefact));
}
else {
cfv[0].first = 0;
cfv[0].second = -prefact;
cfv.push_back(make_pair(1, prefact));
}
}
else if( ( intrip && !outtrip ) ||
( !intrip && outtrip ) ) {
if(!outsex)
cfv[0] = make_pair(0, 1);
else {
cfv[0] = make_pair(0, 1.);
for(unsigned int ix=0;ix<3;++ix)
cfv.push_back(make_pair(ix+1, 1.));
}
}
else if((intrip && outsex) || (intrip && outsexb)) {
cfv[0] = make_pair(0,1.);
for(int ix=1; ix<4; ++ix)
cfv.push_back(make_pair(ix,1.));
}
else
cfv[0] = make_pair(1, 1);
}
}
else if(offshell == PDT::Colour0) {
if( ina == PDT::Colour0 ) {
cfv[0] = make_pair(0, 1);
}
else if(ina==PDT::Colour3 || ina==PDT::Colour3bar) {
if( outa == PDT::Colour0 ) {
cfv[0] = make_pair(0, 1);
}
else if(outa==PDT::Colour3 || outa==PDT::Colour3bar) {
cfv[0] = make_pair(3, 1);
}
else if(outa==PDT::Colour8) {
cfv[0] = make_pair(2, 1);
}
else if(outa==PDT::Colour6 || outa==PDT::Colour6bar) {
cfv[0] = make_pair(8, 1.);
cfv.push_back(make_pair(9,1.));
}
else
assert(false);
}
else if(ina==PDT::Colour8) {
if( outa == PDT::Colour0 ) {
cfv[0] = make_pair(0, 1);
}
else if(outa==PDT::Colour3 || outb==PDT::Colour3bar) {
cfv[0] = make_pair(2, 1);
}
else if(outa==PDT::Colour8) {
cfv[0] = make_pair(6, 1);
}
}
}
else if(offshell == PDT::Colour3 || offshell == PDT::Colour3bar) {
if(outa == PDT::Colour6 || outa == PDT::Colour6bar ||
outb == PDT::Colour6bar || outb == PDT::Colour6) {
cfv[0] = make_pair(6, 1.);
cfv.push_back(make_pair(7,1.));
}
else if((ina == PDT::Colour3 && inb == PDT::Colour3) ||
(ina == PDT::Colour3bar && inb == PDT::Colour3bar)) {
if((outa == PDT::Colour3 && outb == PDT::Colour3 ) ||
(outa == PDT::Colour3bar && outb == PDT::Colour3bar)) {
cfv[0] = make_pair(2, 1.);
cfv.push_back(make_pair(3,-1.));
}
else
cfv[0] = make_pair(0,1.);
}
else if(((ina==PDT::Colour3 && inb==PDT::Colour8) ||
(ina==PDT::Colour3bar && inb==PDT::Colour8) ||
(inb==PDT::Colour3 && ina==PDT::Colour8) ||
(inb==PDT::Colour3bar && ina==PDT::Colour8) ) &&
((outa==PDT::Colour3 && outb==PDT::Colour3 ) ||
(outa==PDT::Colour3bar && outb==PDT::Colour3bar))) {
cfv[0] = make_pair(0,1.);
}
else {
if(outa == PDT::Colour0 || outb == PDT::Colour0)
cfv[0] = make_pair(0, 1);
else
cfv[0] = make_pair(1, 1);
}
}
else if( offshell == PDT::Colour6 || offshell == PDT::Colour6bar) {
if((ina == PDT::Colour3 && inb == PDT::Colour3 &&
outa == PDT::Colour3 && outb == PDT::Colour3 ) ||
(ina == PDT::Colour3bar && inb == PDT::Colour3bar &&
outa == PDT::Colour3bar && outb == PDT::Colour3bar)) {
cfv[0] = make_pair(2,0.5);
cfv.push_back(make_pair(3,0.5));
}
else if((ina == PDT::Colour3 && inb == PDT::Colour3 &&
((outa == PDT::Colour6 && outb == PDT::Colour0)||
(outb == PDT::Colour6 && outa == PDT::Colour0))) ||
(ina == PDT::Colour3bar && inb == PDT::Colour3bar &&
((outa == PDT::Colour6bar && outb == PDT::Colour0)||
(outb == PDT::Colour6bar && outa == PDT::Colour0)))) {
cfv[0] = make_pair(0,0.5);
cfv.push_back(make_pair(1,0.5));
}
else
assert(false);
}
else {
if(outa == PDT::Colour0 || outb == PDT::Colour0)
cfv[0] = make_pair(0, 1);
else
cfv[0] = make_pair(1, 1);
}
diag.colourFlow = cfv;
}
void HardProcessConstructor::fourPointCF(HPDiagram & diag) {
using namespace ThePEG::Helicity;
// count the colours
unsigned int noct(0),ntri(0),nsng(0),nsex(0),nf(0);
vector<tcPDPtr> particles;
for(unsigned int ix=0;ix<4;++ix) {
particles.push_back(getParticleData(diag.ids[ix]));
PDT::Colour col = particles.back()->iColour();
if(col==PDT::Colour0) ++nsng;
else if(col==PDT::Colour3||col==PDT::Colour3bar) ++ntri;
else if(col==PDT::Colour8) ++noct;
else if(col==PDT::Colour6||col==PDT::Colour6bar) ++nsex;
if(particles.back()->iSpin()==2) nf+=1;
}
if(nsng==4 || (ntri==2&&nsng==2) ||
(noct==3 && nsng==1) ||
(ntri==2 && noct==1 && nsng==1) ||
(noct == 2 && nsng == 2) ) {
vector<CFPair> cfv(1,make_pair(0,1));
diag.colourFlow = cfv;
}
else if(noct==4) {
// flows for SSVV, VVVV is handled in me class
vector<CFPair> cfv(6);
cfv[0] = make_pair(0, -2.);
cfv[1] = make_pair(1, -2.);
cfv[2] = make_pair(2, +4.);
cfv[3] = make_pair(3, -2.);
cfv[4] = make_pair(4, +4.);
cfv[5] = make_pair(5, -2.);
diag.colourFlow = cfv;
}
else if(ntri==2&&noct==2) {
vector<CFPair> cfv(2);
cfv[0] = make_pair(0, 1);
cfv[1] = make_pair(1, 1);
if(nf==2) cfv[1].second = -1.;
diag.colourFlow = cfv;
}
else if(nsex==2&&noct==2) {
vector<CFPair> cfv;
for(unsigned int ix=0;ix<4;++ix)
cfv.push_back(make_pair(ix ,2.));
for(unsigned int ix=0;ix<8;++ix)
cfv.push_back(make_pair(4+ix,1.));
diag.colourFlow = cfv;
}
else if(ntri==4) {
// get the order from the vertex
vector<long> temp;
for(unsigned int ix=0;ix<4;++ix) {
temp = diag.vertices.first->search(ix,diag.outgoing.first);
if(!temp.empty()) break;
}
// compute the mapping
vector<long> ids;
ids.push_back( particles[0]->CC() ? -diag.incoming.first : diag.incoming.first );
ids.push_back( particles[1]->CC() ? -diag.incoming.second : diag.incoming.second);
ids.push_back( diag.outgoing.first );
ids.push_back( diag.outgoing.second);
vector<unsigned int> order = {0,1,2,3};
vector<bool> matched(4,false);
for(unsigned int ix=0;ix<temp.size();++ix) {
for(unsigned int iy=0;iy<ids.size();++iy) {
if(matched[iy]) continue;
if(temp[ix]==ids[iy]) {
matched[iy] = true;
order[ix]=iy;
break;
}
}
}
// 3 3 -> 3 3
if((particles[0]->iColour()==PDT::Colour3 &&
particles[1]->iColour()==PDT::Colour3) ||
(particles[0]->iColour()==PDT::Colour3bar &&
particles[1]->iColour()==PDT::Colour3bar) ) {
if(diag.vertices.first->colourStructure()==ColourStructure::SU3I12I34) {
if( (order[0]==0 && order[1]==2) || (order[2]==0 && order[3]==2) ||
(order[0]==2 && order[1]==0) || (order[2]==2 && order[3]==0))
diag.colourFlow = vector<CFPair>(1,make_pair(2,1.));
else
diag.colourFlow = vector<CFPair>(1,make_pair(3,1.));
}
else if(diag.vertices.first->colourStructure()==ColourStructure::SU3I14I23) {
if( (order[0]==0 && order[3]==2) || (order[1]==0 && order[2]==2) ||
(order[0]==2 && order[3]==0) || (order[1]==2 && order[2]==0))
diag.colourFlow = vector<CFPair>(1,make_pair(2,1.));
else
diag.colourFlow = vector<CFPair>(1,make_pair(3,1.));
}
else if(diag.vertices.first->colourStructure()==ColourStructure::SU3T21T43) {
if( (order[1]==0 && order[0]==2) || (order[3]==0 && order[2]==2) ||
(order[1]==2 && order[0]==0) || (order[3]==2 && order[2]==0))
diag.colourFlow = vector<CFPair>(1,make_pair(0,1.));
else
diag.colourFlow = vector<CFPair>(1,make_pair(1,1.));
}
else if(diag.vertices.first->colourStructure()==ColourStructure::SU3T23T41) {
if( (order[1]==0 && order[2]==2) || (order[3]==0 && order[0]==2) ||
(order[1]==2 && order[2]==0) || (order[3]==2 && order[0]==0))
diag.colourFlow = vector<CFPair>(1,make_pair(0,1.));
else
diag.colourFlow = vector<CFPair>(1,make_pair(1,1.));
}
else
assert(false);
}
else if((particles[0]->iColour()==PDT::Colour3 &&
- particles[1]->iColour()==PDT::Colour3bar) |
+ particles[1]->iColour()==PDT::Colour3bar) ||
(particles[0]->iColour()==PDT::Colour3bar &&
particles[1]->iColour()==PDT::Colour3)) {
if(diag.vertices.first->colourStructure()==ColourStructure::SU3I12I34) {
if( (order[0]==0 && order[1]==1) || (order[2]==0 && order[3]==0) ||
(order[0]==1 && order[1]==0) || (order[2]==1 && order[3]==1))
diag.colourFlow = vector<CFPair>(1,make_pair(3,1.));
else
diag.colourFlow = vector<CFPair>(1,make_pair(2,1.));
}
else if(diag.vertices.first->colourStructure()==ColourStructure::SU3I14I23) {
if( (order[0]==0 && order[3]==1) || (order[0]==2 && order[3]==3) ||
(order[0]==1 && order[3]==0) || (order[0]==3 && order[3]==2))
diag.colourFlow = vector<CFPair>(1,make_pair(3,1.));
else
diag.colourFlow = vector<CFPair>(1,make_pair(2,1.));
}
else if(diag.vertices.first->colourStructure()==ColourStructure::SU3T21T43) {
if( (order[1]==0 && order[0]==1) || (order[3]==0 && order[2]==1) ||
(order[1]==1 && order[0]==0) || (order[3]==1 && order[2]==0))
diag.colourFlow = vector<CFPair>(1,make_pair(1,1.));
else
diag.colourFlow = vector<CFPair>(1,make_pair(0,1.));
}
else if(diag.vertices.first->colourStructure()==ColourStructure::SU3T23T41) {
if( (order[1]==0 && order[2]==1) || (order[1]==1 && order[2]==0) ||
(order[1]==3 && order[2]==2) || (order[1]==2 && order[2]==3))
diag.colourFlow = vector<CFPair>(1,make_pair(1,1.));
else
diag.colourFlow = vector<CFPair>(1,make_pair(2,1.));
}
else
assert(false);
}
else {
assert(false);
}
}
else {
assert(false);
}
}
namespace {
// Helper functor for find_if in duplicate function.
class SameDiagramAs {
public:
SameDiagramAs(const HPDiagram & diag) : a(diag) {}
bool operator()(const HPDiagram & b) const {
return a == b;
}
private:
HPDiagram a;
};
}
bool HardProcessConstructor::duplicate(const HPDiagram & diag,
const HPDVector & group) const {
//find if a duplicate diagram exists
HPDVector::const_iterator it =
find_if(group.begin(), group.end(), SameDiagramAs(diag));
return it != group.end();
}
bool HardProcessConstructor::checkOrder(const HPDiagram & diag) const {
for(map<string,pair<unsigned int,int> >::const_iterator it=model_->couplings().begin();
it!=model_->couplings().end();++it) {
int order=0;
if(diag.vertices.first ) order += diag.vertices.first ->orderInCoupling(it->second.first);
if(diag.vertices.second&&diag.vertices.first->getNpoint()==3)
order += diag.vertices.second->orderInCoupling(it->second.first);
if(order>it->second.second) return false;
}
return true;
}
diff --git a/Models/Sextet/SextetFFSVertex.cc b/Models/Sextet/SextetFFSVertex.cc
--- a/Models/Sextet/SextetFFSVertex.cc
+++ b/Models/Sextet/SextetFFSVertex.cc
@@ -1,215 +1,215 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the SextetFFSVertex class.
//
#include "SextetFFSVertex.h"
#include "SextetModel.h"
#include "SextetParticles.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IBPtr SextetFFSVertex::clone() const {
return new_ptr(*this);
}
IBPtr SextetFFSVertex::fullclone() const {
return new_ptr(*this);
}
void SextetFFSVertex::persistentOutput(PersistentOStream & os) const {
os << g1L_ << g1R_ << g1pR_ << g1ppR_ << g3L_;
}
void SextetFFSVertex::persistentInput(PersistentIStream & is, int) {
is >> g1L_ >> g1R_ >> g1pR_ >> g1ppR_ >> g3L_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<SextetFFSVertex,Helicity::FFSVertex>
describeSextetFFSVertex("Herwig::SextetFFSVertex", "HwSextetModel.so");
void SextetFFSVertex::Init() {
static ClassDocumentation<SextetFFSVertex> documentation
("The SextetFFSVertex class implements the coupling of two "
"fermions to a scalar sextet particle.");
}
void SextetFFSVertex::doinit() {
orderInGs (0);
orderInGem(1);
SextetModelPtr model =
dynamic_ptr_cast<SextetModelPtr>(generator()->standardModel());
if(!model) throw Exception() << "Must be using the SextetModel"
<< " in SextetGSSVertex::doinit()"
<< Exception::runerror;
// extract the couplings
g1L_ = model->g1L();
g1R_ = model->g1R();
g1pR_ = model->g1pR();
g1ppR_ = model->g1ppR();
g3L_ = model->g3L();
// add the enabled particles
if(model->ScalarSingletY43Enabled()) {
for(long ix=0;ix<3;++ix) {
long iu = 2*ix + 2;
if(g1ppR_[ix]!=0.) {
addToList( iu, iu, ParticleID::ScalarDQSingletY43bar);
addToList( -iu, -iu, ParticleID::ScalarDQSingletY43);
}
}
}
if(model->ScalarSingletY13Enabled()) {
for(long ix=0;ix<3;++ix) {
long iu = 2*ix + 2;
long id = 2*ix + 1;
if(g1L_[ix]!=0. || g1R_[ix]!=0.) {
addToList( id, iu, ParticleID::ScalarDQSingletY13bar);
addToList( -id, -iu, ParticleID::ScalarDQSingletY13);
}
}
}
if(model->ScalarSingletY23Enabled()) {
for(long ix=0;ix<3;++ix) {
long id = 2*ix + 1;
if(g1pR_[ix]!=0. ) {
addToList( id, id,ParticleID::ScalarDQSingletY23bar);
addToList(-id,-id,ParticleID::ScalarDQSingletY23);
}
}
}
if(model->ScalarTripletY13Enabled()) {
for(long ix=0;ix<3;++ix) {
long iu = 2*ix + 2;
long id = 2*ix + 1;
if(g3L_[ix]!=0. ) {
addToList( iu, iu, ParticleID::ScalarDQTripletPbar);
addToList( -iu, -iu, ParticleID::ScalarDQTripletP);
addToList( iu, id, ParticleID::ScalarDQTriplet0bar);
addToList( -iu, -id, ParticleID::ScalarDQTriplet0);
addToList( id, id, ParticleID::ScalarDQTripletMbar);
addToList( -id, -id, ParticleID::ScalarDQTripletM);
}
}
}
Helicity::FFSVertex::doinit();
}
void SextetFFSVertex::setCoupling(Energy2,tcPDPtr part1,
tcPDPtr part2,tcPDPtr part3) {
long q1ID=(abs(part1->id())), q2ID=(abs(part2->id())),
sDQID=(abs(part3->id()));
//check scalar diquark
assert( sDQID == ParticleID::ScalarDQSingletY43 ||
sDQID == ParticleID::ScalarDQSingletY13 ||
sDQID == ParticleID::ScalarDQSingletY23 ||
sDQID == ParticleID::ScalarDQTripletP ||
sDQID == ParticleID::ScalarDQTriplet0 ||
sDQID == ParticleID::ScalarDQTripletM);
//check quarks
assert(!(q1ID>6) && !(q2ID>6));
bool part1Up = (q1ID==2 || q1ID==4 || q1ID==6);
#ifndef NDEBUG
bool part2Up = (q2ID==2 || q2ID==4 || q2ID==6);
#endif
Complex cRight, cLeft, prefactor(1.);
if(sDQID==ParticleID::ScalarDQSingletY43){
//should both be up type
assert(part1Up && part2Up);
if(q1ID==2)
cRight=Complex(g1ppR_[0]);
else if(q1ID==4)
cRight=Complex(g1ppR_[1]);
else
cRight=Complex(g1ppR_[2]);
cLeft=Complex(0.);
}
if(sDQID==ParticleID::ScalarDQSingletY13){
//should be one up one down type
assert((part1Up && !part2Up) || (!part1Up && part2Up));
long upType;
if(part1Up)
upType=q1ID;
else
upType=q2ID;
if(upType==2){
cRight=Complex(g1R_[0]);
cLeft=Complex(2.*g1L_[0]);
}
else if(upType==4){
cRight=Complex(g1R_[1]);
cLeft=Complex(2.*g1L_[1]);
}
- else
- cRight=Complex(g1R_[2]);{
+ else {
+ cRight=Complex(g1R_[2]);
cLeft=Complex(2.*g1L_[2]);
}
}
if(sDQID==ParticleID::ScalarDQSingletY23){
//should both be down type
assert(!part1Up && !part2Up);
if(q1ID==1)
cRight=Complex(g1pR_[0]);
else if(q1ID==3)
cRight=Complex(g1pR_[1]);
else
cRight=Complex(g1pR_[2]);
cLeft=Complex(0.);
}
if(sDQID==ParticleID::ScalarDQTripletP){
//should both be up type
assert(part1Up && part2Up);
if(q1ID==2)
cLeft=Complex(g3L_[0]);
else if(q1ID==4)
cLeft=Complex(g3L_[1]);
else
cLeft=Complex(g3L_[2]);
cRight=Complex(0.);
}
if(sDQID==ParticleID::ScalarDQTriplet0){
//should both one up and down type
assert((part1Up && !part2Up) || (!part1Up && part2Up));
//possibly doesn't couple
long upType;
if(part1Up)
upType=q1ID;
else
upType=q2ID;
if(upType==2)
cLeft=Complex(g3L_[0]);
else if(upType==4)
cLeft=Complex(g3L_[1]);
else
cLeft=Complex(g3L_[2]);
cRight=Complex(0.);
}
if(sDQID==ParticleID::ScalarDQTripletM){
//should one both be down type
assert(!part1Up && !part2Up);
if(q1ID==1)
cLeft=Complex(g3L_[0]);
else if(q1ID==3)
cLeft=Complex(g3L_[1]);
else
cLeft=Complex(g3L_[2]);
cRight=Complex(0.);
prefactor=Complex(-1.);
}
left(cLeft);
right(cRight);
norm(prefactor);
}
diff --git a/Models/Susy/SSWGSSVertex.cc b/Models/Susy/SSWGSSVertex.cc
--- a/Models/Susy/SSWGSSVertex.cc
+++ b/Models/Susy/SSWGSSVertex.cc
@@ -1,202 +1,196 @@
// -*- C++ -*-
//
// SSWGSSVertex.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 SSWGSSVertex class.
//
#include "SSWGSSVertex.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace ThePEG::Helicity;
using namespace Herwig;
SSWGSSVertex::SSWGSSVertex() : _sw(0.), _cw(0.), _q2last(),_emcouplast(0.),
_scouplast(0.), _ulast(0), _dlast(0),
_gblast(0), _factlast(0.) {
colourStructure(ColourStructure::SU3TFUND);
}
void SSWGSSVertex::doinit() {
//W-
//LL-squarks
for(long ix=1000001;ix<1000006;ix+=2) {
addToList(-24,21,ix+1,-ix);
}
//1-2 stop sbottom
addToList(-24,21,1000006,-2000005);
//2-1 stop sbottom
addToList(-24,21,2000006,-1000005);
//2-2 stop sbottom
addToList(-24,21,2000006,-2000005);
//W+
for(long ix=1000001;ix<1000006;ix+=2) {
addToList(24,21,-(ix+1),ix);
}
//1-2 stop sbottom
addToList(24,21,-1000006,2000005);
//2-1 stop sbottom
addToList(24,21,-2000006,1000005);
//2-2 stop sbottom
addToList(24,21,-2000006,2000005);
//---Z0----
//LL squarks
for(long ix=1000001;ix<1000007;++ix) {
addToList(23,21,ix,-ix);
}
//RR squarks
for(long ix=2000001;ix<2000007;++ix) {
addToList(23,21,ix,-ix);
}
//L-Rbar stop
addToList(23,21,1000006,-2000006);
//Lbar-R stop
addToList(23,21,-1000006,2000006);
//L-Rbar sbottom
addToList(23,21,1000005,-2000005);
//Lbar-R sbottom
addToList(23,21,-1000005,2000005);
//----gamma----
//squarks
for(long ix=1000001;ix<1000007;++ix) {
addToList(22,21,ix,-ix);
}
for(long ix=2000001;ix<2000007;++ix) {
addToList(22,21,ix,-ix);
}
orderInGem(1);
orderInGs(1);
VVSSVertex::doinit();
tMSSMPtr theSS = dynamic_ptr_cast<MSSMPtr>(generator()->standardModel());
if(!theSS)
throw InitException() << "SSWGSSVertex::doinit() - "
<< "The model pointer is null."
<< Exception::abortnow;
_sw = sqrt(sin2ThetaW());
_cw = sqrt( 1. - sqr(_sw) );
_stop = theSS->stopMix();
_sbottom = theSS->sbottomMix();
if(!_stop || !_sbottom)
throw InitException() << "SSWGSSVertex::doinit() - "
<< "A mixing matrix pointer is null."
<< " stop: " << _stop << " sbottom: " << _sbottom
<< Exception::abortnow;
}
void SSWGSSVertex::persistentOutput(PersistentOStream & os) const {
os << _sw << _cw << _stop << _sbottom;
}
void SSWGSSVertex::persistentInput(PersistentIStream & is, int) {
is >> _sw >> _cw >> _stop >> _sbottom;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<SSWGSSVertex,VVSSVertex>
describeHerwigSSWGSSVertex("Herwig::SSWGSSVertex", "HwSusy.so");
void SSWGSSVertex::Init() {
static ClassDocumentation<SSWGSSVertex> documentation
("This implements the gluon-gluon-squark-squark vertex.");
}
void SSWGSSVertex::setCoupling(Energy2 q2, tcPDPtr part1,
tcPDPtr part2,tcPDPtr part3,tcPDPtr part4) {
long boson(abs(part1->id()));
long gluon(abs(part2->id()));
if (gluon > boson) swap(gluon, boson);
if( boson != ParticleID::Wplus && boson != ParticleID::Z0 &&
boson != ParticleID::gamma ) {
throw HelicityConsistencyError()
<< "SSWGSSVertex::setCoupling() - Vector particle in this "
<< "vertex is not a W/Z/gamma. " << boson << Exception::warning;
norm(0.);
}
if( gluon != ParticleID::g ) {
throw HelicityConsistencyError()
<< "SSWGSSVertex::setCoupling() - Vector particle in this "
<< "vertex is not a gluon. " << gluon << Exception::warning;
norm(0.);
}
long sq1(abs(part3->id())),sq2(abs(part4->id()));
- if( (sq1 < 1000001 && sq1 > 1000006 && sq1 < 2000001 && sq1 > 2000006) ||
- (sq2 < 1000001 && sq2 > 1000006 && sq2 < 2000001 && sq2 > 2000006))
- throw HelicityConsistencyError()
- << "SSWGSSVertex::setCoupling() - There are no squarks in "
- << "this vertex! " << part3->id() << " " << part4->id()
- << Exception::warning;
if( sq1 % 2 != 0 ) swap(sq1, sq2);
if( sq1 != _ulast || sq2 != _dlast || boson != _gblast) {
_gblast = boson;
_ulast = sq1;
_dlast = sq2;
//photon is simplest
if( boson == ParticleID::gamma )
_factlast = -2.*getParticleData(sq1)->charge()/eplus;
else {
//determine which helicity state
unsigned int alpha(sq1/1000000 - 1), beta(sq2/1000000 - 1);
//mixing factors
Complex m1a(0.), m1b(0.);
if( sq1 == ParticleID::SUSY_t_1 || sq1 == ParticleID::SUSY_t_2 )
m1a = (*_stop)(alpha, 0);
else if( sq1 == ParticleID::SUSY_b_1 || sq1 == ParticleID::SUSY_b_2 )
m1a = (*_sbottom)(alpha, 0);
else
m1a = (alpha == 0) ? Complex(1.) : Complex(0.);
if( sq2 == ParticleID::SUSY_t_1 || sq2 == ParticleID::SUSY_t_2 )
m1b = (*_stop)(beta, 0);
else if( sq2 == ParticleID::SUSY_b_1 || sq2 == ParticleID::SUSY_b_2 )
m1b = (*_sbottom)(beta, 0);
else
m1b = (beta == 0) ? Complex(1.) : Complex(0.);
//W boson
if( boson == ParticleID::Wplus ) {
_factlast = -1.*m1a*m1b*sqrt(2)/_sw;
}
//Z boson
else {
double lmda(1.);
if( sq2 % 2 == 0 ) lmda = -1.;
_factlast = lmda*m1a*m1b;
if( alpha == beta) {
double ef = getParticleData(sq1)->charge()/eplus;
_factlast += 2.*ef*sqr(_sw);
}
_factlast *= 1./_cw/_sw;
}
}
}
if( q2 != _q2last || _emcouplast==0. || _scouplast==0. ) {
_q2last = q2;
_emcouplast = electroMagneticCoupling(q2);
_scouplast = strongCoupling(q2);
}
norm(-_emcouplast*_scouplast*_factlast);
}
diff --git a/PDF/MPIPDF.cc b/PDF/MPIPDF.cc
--- a/PDF/MPIPDF.cc
+++ b/PDF/MPIPDF.cc
@@ -1,85 +1,82 @@
// -*- C++ -*-
//
// MPIPDF.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MPIPDF class.
//
#include "MPIPDF.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/ParticleData.h"
#include "ThePEG/PDT/EnumParticles.h"
#include <cassert>
using namespace Herwig;
using namespace ThePEG;
-MPIPDF::~MPIPDF() {}
-
-
IBPtr MPIPDF::clone() const {
return new_ptr(*this);
}
IBPtr MPIPDF::fullclone() const {
return new_ptr(*this);
}
bool MPIPDF::canHandleParticle(tcPDPtr particle) const {
assert(thePDF);
return thePDF->canHandleParticle(particle);
}
cPDVector MPIPDF::partons(tcPDPtr particle) const {
assert(thePDF);
return thePDF->partons(particle);
}
double MPIPDF::xfx(tcPDPtr particle, tcPDPtr parton, Energy2 partonScale,
double x, double eps, Energy2 particleScale) const {
// returns the density with removed valence part.
assert(thePDF);
return thePDF->xfsx(particle, parton, partonScale,
x, eps, particleScale);
}
double MPIPDF::xfvx(tcPDPtr particle, tcPDPtr parton, Energy2 partonScale,
double x, double eps, Energy2 particleScale) const {
// Here we should return the actual valence density.
assert(thePDF);
return thePDF->xfvx(particle, parton, partonScale,
x, eps, particleScale);
}
void MPIPDF::persistentOutput(PersistentOStream & os) const {
os << thePDF;
}
void MPIPDF::persistentInput(PersistentIStream & is, int) {
is >> thePDF;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<MPIPDF,PDFBase>
describeHerwigMPIPDF("Herwig::MPIPDF", "HwShower.so");
void MPIPDF::Init() {
static ClassDocumentation<MPIPDF> documentation
("The MPIPDF class wraps other PDF classes to provide "
"sea-quark-only PDFs.");
}
diff --git a/PDF/MPIPDF.h b/PDF/MPIPDF.h
--- a/PDF/MPIPDF.h
+++ b/PDF/MPIPDF.h
@@ -1,156 +1,147 @@
// -*- C++ -*-
//
// MPIPDF.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MPIPDF_H
#define HERWIG_MPIPDF_H
//
// This is the declaration of the MPIPDF class.
//
#include "ThePEG/PDF/PDFBase.h"
#include "MPIPDF.fh"
namespace Herwig {
using namespace ThePEG;
/**
* The MPIPDF class defines
* a modified pdf which uses an existing pdf object to add
* modifications like removing the valence part of it, which
* is needed in the backward evolution of secondary scatters.
*
* \author Manuel B\"ahr
*
* @see \ref MPIPDFInterfaces "The interfaces"
* defined for MPIPDF.
*/
class MPIPDF: public PDFBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
-
/**
* The constructor which takes a PDF object as argument, to work with.
*/
MPIPDF(cPDFPtr orig = cPDFPtr()) : thePDF(orig) {}
- /**
- * The destructor.
- */
- virtual ~MPIPDF();
- //@}
-
public:
/** @name Virtual functions to be overridden by sub-classes. */
//@{
/**
* Return true if this PDF can handle the extraction of partons from
* the given \a particle.
*/
virtual bool canHandleParticle(tcPDPtr particle) const;
/**
* Return the partons which this PDF may extract from the given
* \a particle.
*/
virtual cPDVector partons(tcPDPtr particle) const;
/**
* The density. Return the pdf for the given \a parton inside the
* given \a particle for the virtuality \a partonScale and momentum
* fraction \a x. The \a particle is assumed to have a virtuality \a
* particleScale. For MPIPDF, only the sea quark densities
* are included here!
*/
virtual double xfx(tcPDPtr particle, tcPDPtr parton, Energy2 partonScale,
double x, double eps = 0.0,
Energy2 particleScale = ZERO) const;
/**
* The valence density. Return the pdf for the given cvalence \a
* parton inside the given \a particle for the virtuality \a
* partonScale and momentum fraction \a x. The \a particle is
* assumed to have a virtuality \a particleScale. If not overidden
* by a sub class this implementation will assume that the
* difference between a quark and anti-quark distribution is due do
* valense quarks, but return zero for anything else.
*/
virtual double xfvx(tcPDPtr particle, tcPDPtr parton, Energy2 partonScale,
double x, double eps = 0.0,
Energy2 particleScale = ZERO) 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.
*/
MPIPDF & operator=(const MPIPDF &) = delete;
/**
* pointer to the underlying ThePEG::PDFBase object, we are modifying.
*/
cPDFPtr thePDF;
};
}
#endif /* HERWIG_MPIPDF_H */
diff --git a/PDF/MinBiasPDF.h b/PDF/MinBiasPDF.h
--- a/PDF/MinBiasPDF.h
+++ b/PDF/MinBiasPDF.h
@@ -1,161 +1,146 @@
// -*- C++ -*-
//
// MinBiasPDF.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MinBiasPDF_H
#define HERWIG_MinBiasPDF_H
//
// This is the declaration of the MinBiasPDF class.
//
#include "ThePEG/PDF/PDFBase.h"
#include "MinBiasPDF.fh"
namespace Herwig {
using namespace ThePEG;
/**
* The MinBiasPDF class defines
* a modified pdf which uses an existing pdf object to add
* modifications like removing the valence part of it, which
* is needed in the backward evolution of secondary scatters.
*
* \author Manuel B\"ahr
*
* @see \ref MinBiasPDFInterfaces "The interfaces"
* defined for MinBiasPDF.
*/
class MinBiasPDF: public PDFBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MinBiasPDF() : thePDF(PDFPtr()) {}
- /**
- * The copy constructor.
- */
- MinBiasPDF(const MinBiasPDF & x) :
- PDFBase(x), thePDF(x.thePDF) {}
-
- /**
- * The destructor.
- */
- virtual ~MinBiasPDF() {}
-
- //@}
-
public:
/** @name Virtual functions to be overridden by sub-classes. */
//@{
/**
* Return true if this PDF can handle the extraction of partons from
* the given \a particle.
*/
virtual bool canHandleParticle(tcPDPtr particle) const;
/**
* Return the partons which this PDF may extract from the given
* \a particle.
*/
virtual cPDVector partons(tcPDPtr particle) const;
/**
* The density. Return the pdf for the given \a parton inside the
* given \a particle for the virtuality \a partonScale and momentum
* fraction \a x. The \a particle is assumed to have a virtuality \a
* particleScale.
*/
virtual double xfx(tcPDPtr particle, tcPDPtr parton, Energy2 partonScale,
double x, double eps=0.0, Energy2 particleScale = ZERO) const;
/**
* The valence density. Return the pdf for the given cvalence \a
* parton inside the given \a particle for the virtuality \a
* partonScale and momentum fraction \a x. The \a particle is
* assumed to have a virtuality \a particleScale. If not overidden
* by a sub class this implementation will assume that the
* difference between a quark and anti-quark distribution is due do
* valense quarks, but return zero for anything else.
*/
virtual double xfvx(tcPDPtr particle, tcPDPtr parton, Energy2 partonScale,
double x, double eps=0.0, Energy2 particleScale = ZERO) const;
//@}
/** return the underlying PDFBase pointer*/
tcPDFPtr originalPDF() const {return thePDF;}
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 { return new_ptr(*this); }
/** 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 { return new_ptr(*this); }
//@}
// 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.
*/
MinBiasPDF & operator=(const MinBiasPDF &) = delete;
/**
* pointer to the underlying ThePEG::PDFBase object, we are modifying.
*/
PDFPtr thePDF;
};
}
#endif /* HERWIG_MinBiasPDF_H */
diff --git a/PDF/SatPDF.cc b/PDF/SatPDF.cc
--- a/PDF/SatPDF.cc
+++ b/PDF/SatPDF.cc
@@ -1,118 +1,116 @@
// -*- C++ -*-
//
// SatPDF.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 SatPDF class.
//
#include "SatPDF.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#ifdef ThePEG_TEMPLATES_IN_CC_FILE
// #include "SatPDF.tcc"
#endif
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/PDT/ParticleData.h"
#include "ThePEG/PDT/EnumParticles.h"
#include <cassert>
using namespace Herwig;
using namespace ThePEG;
-SatPDF::~SatPDF() {}
-
bool SatPDF::canHandleParticle(tcPDPtr particle) const {
assert(thePDF);
return thePDF->canHandleParticle(particle);
}
cPDVector SatPDF::partons(tcPDPtr particle) const {
assert(thePDF);
return thePDF->partons(particle);
}
double SatPDF::xfx(tcPDPtr particle, tcPDPtr parton, Energy2 partonScale,
double x, double eps, Energy2 particleScale) const {
assert(thePDF);
double xUsed(x);
if( x < theX0 )
xUsed = theX0;
double pdf(thePDF->xfx(particle, parton, partonScale,
xUsed, eps, particleScale));
if( x < theX0 )
pdf *= pow(x/theX0, theExp);
return pdf;
}
double SatPDF::xfvx(tcPDPtr particle, tcPDPtr parton, Energy2 partonScale,
double x, double eps, Energy2 particleScale) const {
// Here we should return the actual valence density.
assert(thePDF);
double xUsed(x);
if( x < theX0 )
xUsed = theX0;
double pdf(thePDF->xfvx(particle, parton, partonScale,
xUsed, eps, particleScale));
if( x < theX0 )
pdf *= pow(x/theX0, theExp);
return pdf;
}
void SatPDF::persistentOutput(PersistentOStream & os) const {
os << thePDF << theX0 << theExp;
}
void SatPDF::persistentInput(PersistentIStream & is, int) {
is >> thePDF >> theX0 >> theExp;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<SatPDF,PDFBase>
describeHerwigSatPDF("Herwig::SatPDF", "HwSatPDF.so");
void SatPDF::Init() {
static ClassDocumentation<SatPDF> documentation
("SatPDF is used to modify any given parton density for small values of x. That can be used to mimic saturation effects.");
static Reference<SatPDF,PDFBase> interfacePDF
("PDF",
"pointer to the pdf, which will be modified",
&SatPDF::thePDF, false, false, true, false);
static Parameter<SatPDF,double> interfaceX0
("X0",
"For x values below this one the parametrisation: f(x) = f(x0) * (x/x0)**exp is used",
&SatPDF::theX0, 1.E-4, 0.0, 1.0,
true, false, Interface::limited);
static Parameter<SatPDF,double> interfaceExp
("Exp",
"For x values below X0 the parametrisation: f(x) = f(x0) * (x/x0)**exp is used",
&SatPDF::theExp, 0.0, -10.0, 10.0,
true, false, Interface::limited);
}
diff --git a/PDF/SatPDF.h b/PDF/SatPDF.h
--- a/PDF/SatPDF.h
+++ b/PDF/SatPDF.h
@@ -1,172 +1,158 @@
// -*- C++ -*-
//
// SatPDF.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_SatPDF_H
#define HERWIG_SatPDF_H
//
// This is the declaration of the SatPDF class.
//
#include "ThePEG/PDF/PDFBase.h"
namespace Herwig {
using namespace ThePEG;
/**
* The SatPDF class defines
* a modified pdf which uses an existing pdf object to add
* modifications like removing the valence part of it, which
* is needed in the backward evolution of secondary scatters.
*
* \author Manuel B\"ahr
*
* @see \ref SatPDFInterfaces "The interfaces"
* defined for SatPDF.
*/
class SatPDF: public PDFBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
inline SatPDF() : thePDF(PDFPtr()), theX0(1E-4), theExp(0.0) {}
- /**
- * The copy constructor.
- */
- inline SatPDF(const SatPDF & x) :
- PDFBase(x), thePDF(x.thePDF), theX0(x.theX0), theExp(x.theExp) {}
-
- /**
- * The destructor.
- */
- virtual ~SatPDF();
- //@}
-
public:
/** @name Virtual functions to be overridden by sub-classes. */
//@{
/**
* Return true if this PDF can handle the extraction of partons from
* the given \a particle.
*/
virtual bool canHandleParticle(tcPDPtr particle) const;
/**
* Return the partons which this PDF may extract from the given
* \a particle.
*/
virtual cPDVector partons(tcPDPtr particle) const;
/**
* The density. Return the pdf for the given \a parton inside the
* given \a particle for the virtuality \a partonScale and momentum
* fraction \a x. The \a particle is assumed to have a virtuality \a
* particleScale.
*/
virtual double xfx(tcPDPtr particle, tcPDPtr parton, Energy2 partonScale,
double x, double eps=0.0, Energy2 particleScale = ZERO) const;
/**
* The valence density. Return the pdf for the given cvalence \a
* parton inside the given \a particle for the virtuality \a
* partonScale and momentum fraction \a x. The \a particle is
* assumed to have a virtuality \a particleScale. If not overidden
* by a sub class this implementation will assume that the
* difference between a quark and anti-quark distribution is due do
* valense quarks, but return zero for anything else.
*/
virtual double xfvx(tcPDPtr particle, tcPDPtr parton, Energy2 partonScale,
double x, double eps=0.0, Energy2 particleScale = ZERO) 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.
*/
inline virtual IBPtr clone() const { return new_ptr(*this); }
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
inline virtual IBPtr fullclone() const { return new_ptr(*this); }
//@}
// 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.
*/
SatPDF & operator=(const SatPDF &) = delete;
/**
* pointer to the underlying ThePEG::PDFBase object, we are modifying.
*/
PDFPtr thePDF;
/**
* x from where the extrapolation f(x) = f(theX0) * (x/theX0)**theExp
* is used for the pdf's.
*/
double theX0;
/**
* the exponent of the pdf extrapolation for small x (x < theX0).
*/
double theExp;
};
}
#ifndef HERWIG_TEMPLATES_IN_CC_FILE
// #include "SatPDF.tcc"
#endif
#endif /* HERWIG_SatPDF_H */
diff --git a/PDT/HeavyMesonWidthGenerator.cc b/PDT/HeavyMesonWidthGenerator.cc
--- a/PDT/HeavyMesonWidthGenerator.cc
+++ b/PDT/HeavyMesonWidthGenerator.cc
@@ -1,252 +1,252 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the HeavyMesonWidthGenerator class.
//
#include "HeavyMesonWidthGenerator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/Decay/HeavyMeson/HQETStrongDecayer.h"
using namespace Herwig;
HeavyMesonWidthGenerator::HeavyMesonWidthGenerator()
: fPi_(130.2*MeV), g_(0.566), gp_(0.189), h_(0.544), hp_(0.413), k_(0.407), kp_(0.242), gtilde_(0.283),
psiL_(0.), psiS_(0.041), Lambda_(1.*GeV), couplingsSet_(false)
{}
IBPtr HeavyMesonWidthGenerator::clone() const {
return new_ptr(*this);
}
IBPtr HeavyMesonWidthGenerator::fullclone() const {
return new_ptr(*this);
}
void HeavyMesonWidthGenerator::persistentOutput(PersistentOStream & os) const {
os << ounit(fPi_,MeV) << g_ << gp_ << h_ << hp_ << k_ << kp_ << gtilde_
<< psiL_ << psiS_ << ounit(Lambda_,GeV) << couplingsSet_;
}
void HeavyMesonWidthGenerator::persistentInput(PersistentIStream & is, int) {
is >> iunit(fPi_,MeV) >> g_ >> gp_ >> h_ >> hp_ >> k_ >> kp_ >> gtilde_
>> psiL_ >> psiS_ >> iunit(Lambda_,GeV) >> couplingsSet_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<HeavyMesonWidthGenerator,GenericWidthGenerator>
describeHerwigHeavyMesonWidthGenerator("Herwig::HeavyMesonWidthGenerator", "HwHMDecay.so");
void HeavyMesonWidthGenerator::Init() {
static ClassDocumentation<HeavyMesonWidthGenerator> documentation
("The HeavyMesonWidthGenerator class calculates the width for heavy meson decays");
static Parameter<HeavyMesonWidthGenerator,Energy> interfacefPi
("fPi",
"The pion decay constant",
&HeavyMesonWidthGenerator::fPi_, MeV, 130.2*MeV, 100.0*MeV, 200.0*MeV,
false, false, Interface::limited);
static Parameter<HeavyMesonWidthGenerator,double> interfaceg
("g",
"The coupling for 1S (0-,1-) decays",
&HeavyMesonWidthGenerator::g_, 0.566, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<HeavyMesonWidthGenerator,double> interfacegp
("gp",
"The coupling for 1S (0+,1+) decays",
&HeavyMesonWidthGenerator::gp_, 0.189, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<HeavyMesonWidthGenerator,double> interfaceh
("h",
"The coupling for 1P (0+,1+) decays",
&HeavyMesonWidthGenerator::h_, 0.544, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<HeavyMesonWidthGenerator,double> interfacehp
("hp",
"The coupling for 1P (1+,2+) decays",
&HeavyMesonWidthGenerator::hp_, 0.413, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<HeavyMesonWidthGenerator,double> interfacek
("k",
"The coupling for 1D (2-,3-) decays",
&HeavyMesonWidthGenerator::k_, 0.407, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<HeavyMesonWidthGenerator,double> interfacekp
("kp",
"The coupling for 1D (1-,2-) decays",
&HeavyMesonWidthGenerator::kp_, 0.242, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<HeavyMesonWidthGenerator,double> interfacegtilde
("gtilde",
"The coupling for 2S (0-,1-) decays",
&HeavyMesonWidthGenerator::gtilde_, 0.283, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<HeavyMesonWidthGenerator,Energy> interfacefLambda
("Lambda",
"Strong decays momentum scale",
&HeavyMesonWidthGenerator::Lambda_, GeV, 1.*GeV, .1*GeV, 2.*GeV,
false, false, Interface::limited);
static Parameter<HeavyMesonWidthGenerator,double> interfacefpsiL
("psiL",
"D_1 mixing angle for up and down heavy mesons",
&HeavyMesonWidthGenerator::psiL_, 0., -M_PI/2., M_PI/2.,
false, false, Interface::limited);
static Parameter<HeavyMesonWidthGenerator,double> interfacefpsiS
("psiS",
"D_1 mixing angle for strange heavy mesons",
&HeavyMesonWidthGenerator::psiS_, 0.041, -M_PI/2., M_PI/2.,
false, false, Interface::limited);
}
void HeavyMesonWidthGenerator::setupMode(tcDMPtr, tDecayIntegratorPtr decayer,
unsigned int) {
// cast the decayer
Ptr<HQETStrongDecayer>::tcptr strong = dynamic_ptr_cast<Ptr<HQETStrongDecayer>::tcptr >(decayer);
if(strong) {
if(!couplingsSet_) {
fPi_ = strong->fPi_ ;
g_ = strong->g_ ;
gp_ = strong->gp_ ;
h_ = strong->h_ ;
hp_ = strong->hp_ ;
k_ = strong->k_ ;
kp_ = strong->kp_ ;
gtilde_ = strong->gtilde_;
psiL_ = strong->psiL_ ;
psiS_ = strong->psiS_ ;
Lambda_ = strong->Lambda_;
couplingsSet_ = true;
}
}
}
void HeavyMesonWidthGenerator::dataBaseOutput(ofstream & output, bool header) {
if(header) output << "update Width_Generators set parameters=\"";
// info from the base class
GenericWidthGenerator::dataBaseOutput(output,false);
// info from this class
output << "newdef " << name() << ":fPi " << fPi_/MeV << "\n";
output << "newdef " << name() << ":g " << g_ << "\n";
output << "newdef " << name() << ":gp " << gp_ << "\n";
output << "newdef " << name() << ":h " << h_ << "\n";
output << "newdef " << name() << ":hp " << hp_ << "\n";
output << "newdef " << name() << ":k " << k_ << "\n";
output << "newdef " << name() << ":kp " << kp_ << "\n";
output << "newdef " << name() << ":gtilde " << gtilde_ << "\n";
output << "newdef " << name() << ":Lambda " << Lambda_/GeV << "\n";
output << "newdef " << name() << ":psiL " << psiL_ << "\n";
output << "newdef " << name() << ":psiS " << psiS_ << "\n";
if(header) output << "\n\" where BINARY ThePEGName=\"" << name() << "\";"
<< endl;
}
Energy HeavyMesonWidthGenerator::partial2BodyWidth(int imode, Energy q,Energy m1,
Energy m2) const {
if(q<m1+m2) return ZERO;
// mode from the base class
int mecode(MEcode(imode));
if(mecode<=100) {
return GenericWidthGenerator::partial2BodyWidth(imode,q,m1,m2);
}
// calcluate the decay momentum
Energy2 q2(q*q),m12(m1*m1),m22(m2*m2),
pcm2(0.25*(q2*(q2-2.*m12-2.*m22)+(m12-m22)*(m12-m22))/q2);
- Energy pcm(sqrt(pcm2)),gam(ZERO),msum(q+m1);
+ Energy pcm(sqrt(pcm2));
double test=0.;
if(mecode==101) {
test = 4.*sqr(g_)*q/m1*sqr(pcm)/sqr(fPi_);
}
else if(mecode==102) {
test = 4.*sqr(g_)*m1*sqr(pcm)/3./sqr(fPi_)/q;
}
else if(mecode==103) {
test = 8.*sqr(g_)*m1*sqr(pcm)/3./sqr(fPi_)/q;
}
else if(mecode==104) {
long id = abs(particle()->id());
double psi = (id%100)/10!=3 ? psiL_ : psiS_;
unsigned int itemp = abs(id)-abs(id)%1000;
double mix1(cos(psi)),mix2(sin(psi));
if(itemp==20000) {
swap(mix1,mix2);
mix1 *=-1.;
}
InvEnergy2 A = -2.*sqrt(2.*m1/3./q)*hp_*mix1/fPi_/Lambda_;
double B = -h_*mix2/1/fPi_*sqrt(m1/q)/q*(sqr(q)-sqr(m1)+sqr(m2));
B += A*sqr(pcm);
test = (3.*sqr(A*q*sqr(pcm)) +sqr(B)/3.*(3.*sqr(m1)+sqr(pcm))
-A*B*sqr(pcm)*(sqr(q)+sqr(m1)-sqr(m2)))/sqr(m1);
}
else if(mecode==105) {
test = 32.*sqr(hp_)*m1*sqr(sqr(pcm))/15./sqr(fPi_)/sqr(Lambda_)/q;
}
else if(mecode==106) {
test = 16.*sqr(hp_)*m1*sqr(sqr(pcm))/5./sqr(fPi_)/sqr(Lambda_)/q;
}
else if(mecode==107) {
test = sqr(h_)/sqr(fPi_)*m1/pow<3,1>(q)*sqr(sqr(q)-sqr(m1)+sqr(m2));
}
else if(mecode==108) {
test = 8.*m1*sqr(kp_*pcm*(sqr(q)-sqr(m1)+sqr(m2)))/9./sqr(fPi_*Lambda_*q)/q;
}
else if(mecode==109) {
test = 4.*m1*sqr(kp_*pcm*(sqr(q)-sqr(m1)+sqr(m2)))/9./sqr(fPi_*Lambda_*q)/q;
}
else if(mecode==110) {
test = 2.*sqr(kp_*pcm*(sqr(q)-sqr(m1)+sqr(m2)))/15./sqr(fPi_*Lambda_)/m2/pow<5,1>(q)*
(sqr(q)*(sqr(q)+8.*sqr(m1)-2.*sqr(m2))+sqr(sqr(m1)-sqr(m2)));
}
else if(mecode==111) {
test = 32.*sqr(k_)*pow<6,1>(pcm)/225./sqr(fPi_*sqr(Lambda_))/m1/pow<3,1>(q)*
(sqr(q)*(16.*sqr(q)-2.*sqr(m1)+8.*sqr(m2))+sqr(sqr(m1)-sqr(m2)));
}
else if(mecode==112) {
test = 32.*sqr(k_)*m1/35./q*pow<6,1>(pcm)/sqr(fPi_*sqr(Lambda_));
}
else if(mecode==113) {
test = 128.*sqr(k_)*m1/q*pow<6,1>(pcm)/105./sqr(fPi_*sqr(Lambda_));
}
else if(mecode==114) {
test = 4.*sqr(gtilde_)*q/m1*sqr(pcm)/sqr(fPi_);
}
else if(mecode==115) {
test = 4.*sqr(gtilde_)*m1*sqr(pcm)/3./sqr(fPi_)/q;
}
else if(mecode==116) {
test = 8.*sqr(gtilde_)*m1*sqr(pcm)/3./sqr(fPi_)/q;
}
else if(mecode==117) {
long id = abs(particle()->id());
double psi = (id%100)/10!=3 ? psiL_ : psiS_;
unsigned int itemp = abs(id)-abs(id)%1000;
double mix1(cos(psi)),mix2(sin(psi));
if(itemp==20000) {
swap(mix1,mix2);
mix1 *=-1.;
}
test = 4.*sqr(gp_*mix2)*m1*sqr(pcm)/3./sqr(fPi_)/q;
}
else
assert(false);
return test*pcm/8./Constants::pi*MEcoupling(imode)*MEcoupling(imode);
}
diff --git a/Sampling/BinSampler.cc b/Sampling/BinSampler.cc
--- a/Sampling/BinSampler.cc
+++ b/Sampling/BinSampler.cc
@@ -1,730 +1,728 @@
// -*- C++ -*-
//
// BinSampler.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 BinSampler class.
//
#include "BinSampler.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Repository/Repository.h"
#include "ThePEG/Utilities/ColourOutput.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Handlers/StandardEventHandler.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "Herwig/Utilities/Progress.h"
#include "GeneralSampler.h"
using namespace Herwig;
BinSampler::BinSampler()
: MultiIterationStatistics(),
theBias(1.),
theWeighted(false),
theInitialPoints(1000000),
theNIterations(1),
theEnhancementFactor(1.0),
theNonZeroInPresampling(false),
theHalfPoints(false),
theMaxNewMax(30),
theReferenceWeight(1.0),
theBin(-1),
theInitialized(false),
theRemapperPoints(0),
theRemapChannelDimension(false),
theLuminosityMapperBins(0),
theGeneralMapperBins(0),
theRemapperMinSelection(0.00001),
theIntegrated(false),
theRemappersFilled(false),
theHasGrids(false),
theKappa(1.){}
-BinSampler::~BinSampler() {}
-
IBPtr BinSampler::clone() const {
return new_ptr(*this);
}
IBPtr BinSampler::fullclone() const {
return new_ptr(*this);
}
void BinSampler::sampler(Ptr<GeneralSampler>::tptr s) {
theSampler = s;
}
Ptr<GeneralSampler>::tptr BinSampler::sampler() const {
return theSampler;
}
string BinSampler::process() const {
ostringstream os("");
const StandardEventHandler& eh = *theEventHandler;
const StandardXComb& xc = *eh.xCombs()[theBin];
os << xc.matrixElement()->name() << " : ";
os << xc.mePartonData()[0]->PDGName() << " "
<< xc.mePartonData()[1]->PDGName() << " -> ";
for ( cPDVector::const_iterator pid =
xc.mePartonData().begin() + 2;
pid != xc.mePartonData().end(); ++pid )
os << (**pid).PDGName() << " ";
return os.str();
}
string BinSampler::shortprocess() const {
ostringstream os("");
const StandardEventHandler& eh = *theEventHandler;
const StandardXComb& xc = *eh.xCombs()[theBin];
os << xc.mePartonData()[0]->id() << " "
<< xc.mePartonData()[1]->id() << " : ";
for ( cPDVector::const_iterator pid =
xc.mePartonData().begin() + 2;
pid != xc.mePartonData().end(); ++pid )
os << (**pid).id() << " ";
return os.str();
}
string BinSampler::id() const {
ostringstream os("");
const StandardEventHandler& eh = *theEventHandler;
const StandardXComb& xc = *eh.xCombs()[theBin];
string name = xc.matrixElement()->name();
string::size_type i = name.find_first_of("[");
string nameFirst = name.substr(0,i);
i = name.find_first_of("]");
string nameSecond = name.substr(i+1);
os << nameFirst << nameSecond << ":";
for ( cPDVector::const_iterator pid =
xc.mePartonData().begin();
pid != xc.mePartonData().end(); ++pid )
os << (**pid).id() << (pid != (--xc.mePartonData().end()) ? "," : "");
return os.str();
}
double BinSampler::evaluate(vector<double> p,
bool remap) {
double w = 1.0;
if ( remap && !remappers.empty() ) {
for ( size_t k = 0; k < p.size(); ++k ) {
map<size_t,Remapper>::const_iterator r =
remappers.find(k);
if ( r != remappers.end() ) {
pair<double,double> f = r->second.generate(p[k]);
p[k] = f.first;
w /= f.second;
}
}
}
try {
w *= eventHandler()->dSigDR(p) / nanobarn;
} catch (Veto&) {
w = 0.0;
} catch (...) {
throw;
}
if (randomNumberString()!="")
for ( size_t k = 0; k < p.size(); ++k ) {
RandomNumberHistograms[RandomNumberIndex(id(),k)].first.book(p[k],w);
RandomNumberHistograms[RandomNumberIndex(id(),k)].second+=w;
}
return w;
}
double BinSampler::generate() {
double w = 1.;
for ( size_t k = 0; k < lastPoint().size(); ++k ) {
lastPoint()[k] = UseRandom::rnd();
}
try {
w = evaluate(lastPoint());
} catch (Veto&) {
w = 0.0;
} catch (...) {
throw;
}
if ( !weighted() && initialized() ) {
double p = min(abs(w),kappa()*referenceWeight())/(kappa()*referenceWeight());
double sign = w >= 0. ? 1. : -1.;
if ( p < 1 && UseRandom::rnd() > p )
w = 0.;
else
w = sign*max(abs(w),referenceWeight()*kappa());
}
select(w);
if ( w != 0.0 )
accept();
assert(kappa()==1.||sampler()->almostUnweighted());
return w;
}
void BinSampler::fillRemappers(bool progress) {
if ( remappers.empty() )
return;
unsigned long nanPoints = 0;
progress_display* progressBar = nullptr;
if ( progress ) {
Repository::clog() << "warming up " << ANSI::red << process() << ANSI::reset;
progressBar = new progress_display{ theRemapperPoints, Repository::clog() };
}
unsigned long countzero =0;
for ( unsigned long k = 0; k < theRemapperPoints; ++k,++countzero ) {
if (countzero>=theRemapperPoints)break;
double w = 1.;
for ( size_t j = 0; j < lastPoint().size(); ++j ) {
lastPoint()[j] = UseRandom::rnd();
}
try {
w = evaluate(lastPoint(),false);
} catch (Veto&) {
w = 0.0;
} catch (...) {
throw;
}
if ( ! isfinite(w) )
++nanPoints;
if ( theNonZeroInPresampling && w==0. ){
k--;
continue;
}
if ( w != 0.0 ) {
countzero=0;
for ( map<size_t,Remapper>::iterator r = remappers.begin();
r != remappers.end(); ++r )
r->second.fill(lastPoint()[r->first],w);
}
if ( progressBar )
++(*progressBar);
}
if ( progressBar ) {
delete progressBar;
}
if ( nanPoints ) {
Repository::clog() << "Warning: " << nanPoints
<< " out of " << theRemapperPoints << " points with nan or inf "
<< "weight encountered while filling remappers.\n" << flush;
}
}
void BinSampler::saveIntegrationData() const {
XML::Element stats = MultiIterationStatistics::toXML();
stats.appendAttribute("process",id());
sampler()->grids().append(stats);
}
void BinSampler::readIntegrationData() {
if ( theIntegrated )
return;
bool haveStats = false;
list<XML::Element>::iterator sit = sampler()->grids().children().begin();
for ( ; sit != sampler()->grids().children().end(); ++sit ) {
if ( sit->type() != XML::ElementTypes::Element )
continue;
if ( sit->name() != "MultiIterationStatistics" )
continue;
string proc;
sit->getFromAttribute("process",proc);
if ( proc == id() ) {
haveStats = true;
break;
}
}
if ( haveStats ) {
MultiIterationStatistics::fromXML(*sit);
sampler()->grids().erase(sit);
theIntegrated = true;
} else {
throw Exception()
<< "\n---------------------------------------------------\n\n"
<< "Expected integration data.\n\n"
<< "* When using the build setup make sure the integrate command has been run.\n\n"
<< "* Check the [EventGenerator].log file for further information.\n\n"
<< "* Make sure that the Herwig folder can be found and that it contains a HerwigGrids.xml file.\n\n"
<< "* If you have split the integration jobs, make sure that each integration job was finished.\n"
<< " Afterwards delete the global HerwigGrids.xml file in the Herwig subfolder\n"
<< " to automatically create an updated version of the global HerwigGrids.xml file.\n\n"
<< "---------------------------------------------------\n"
<< Exception::abortnow;
}
}
void BinSampler::saveRemappers() const {
if ( remappers.empty() )
return;
XML::Element maps(XML::ElementTypes::Element,"Remappers");
maps.appendAttribute("process",id());
for ( map<size_t,Remapper>::const_iterator r = remappers.begin();
r != remappers.end(); ++r ) {
XML::Element rmap = r->second.toXML();
rmap.appendAttribute("dimension",r->first);
maps.append(rmap);
}
sampler()->grids().append(maps);
}
void BinSampler::setupRemappers(bool progress) {
if ( !theRemapperPoints )
return;
if ( theRemappersFilled )
return;
lastPoint().resize(dimension());
bool haveGrid = false;
list<XML::Element>::iterator git = sampler()->grids().children().begin();
for ( ; git != sampler()->grids().children().end(); ++git ) {
if ( git->type() != XML::ElementTypes::Element )
continue;
if ( git->name() != "Remappers" )
continue;
string proc;
git->getFromAttribute("process",proc);
if ( proc == id() ) {
haveGrid = true;
break;
}
}
if ( haveGrid ) {
for ( list<XML::Element>::iterator cit = git->children().begin();
cit != git->children().end(); ++cit ) {
if ( cit->type() != XML::ElementTypes::Element )
continue;
if ( cit->name() != "Remapper" )
continue;
size_t dimension = 0;
cit->getFromAttribute("dimension",dimension);
remappers[dimension].fromXML(*cit);
}
sampler()->grids().erase(git);
}
if ( !haveGrid ) {
const StandardEventHandler& eh = *eventHandler();
const StandardXComb& xc = *eh.xCombs()[bin()];
const pair<int,int>& pdims = xc.partonDimensions();
set<int> remapped;
if ( theRemapChannelDimension && xc.diagrams().size() > 1 &&
dimension() > pdims.first + pdims.second ) {
remappers[pdims.first] = Remapper(xc.diagrams().size(),theRemapperMinSelection,false);
remapped.insert(pdims.first);
}
if ( theLuminosityMapperBins > 1 && dimension() >= pdims.first + pdims.second ) {
for ( int n = 0; n < pdims.first; ++n ) {
remappers[n] = Remapper(theLuminosityMapperBins,theRemapperMinSelection,true);
remapped.insert(n);
}
for ( int n = dimension() - pdims.second; n < dimension(); ++n ) {
remappers[n] = Remapper(theLuminosityMapperBins,theRemapperMinSelection,true);
remapped.insert(n);
}
}
if ( theGeneralMapperBins > 1 ) {
for ( int n = 0; n < dimension(); n++ ) {
if ( remapped.find(n) == remapped.end() ) {
remappers[n] = Remapper(theGeneralMapperBins,theRemapperMinSelection,true);
remapped.insert(n);
}
}
}
fillRemappers(progress);
for ( map<size_t,Remapper>::iterator r = remappers.begin();
r != remappers.end(); ++r ) {
r->second.finalize();
}
}
theRemappersFilled = true;
}
void BinSampler::runIteration(unsigned long points, bool progress) {
progress_display* progressBar = 0;
if ( progress ) {
Repository::clog() << "integrating " << ANSI::red << process()<< ANSI::reset << ", iteration "
<< (iterations().size() + 1);
progressBar = new progress_display(points,Repository::clog());
}
double w=0.;
double maxweight=0;
int numlastmax=0;
unsigned long countzero =0;
int newmax=0;
for ( unsigned long k = 0; k < points; ++k,++countzero ) {
if (countzero>=points)break;
w=abs(generate());
if(theNonZeroInPresampling && w==0.0){
k--;
continue;
}
if (w!=0.0)
countzero =0;
numlastmax++;
if (theHalfPoints&&maxweight<w&&
numlastmax<(int)(points/2.)){
if(++newmax>theMaxNewMax){
throw Exception()
<< "\n---------------------------------------------------\n\n"
<< "To many new Maxima.\n\n"
<< "* With the option:\n\n"
<< "* set Sampler:BinSampler:HalfPoints Yes\n\n"
<< "* for every new maximum weight found until the half of the persampling points\n"
<< "* the counter is set to zero. We count the number of new maxima.\n"
<< "* You have reached: "<<newmax<<"\n"
<< "* Did you apply reasonable cuts to the process?\n"
<< "* You can set the maximum allowed new maxima by:"
<< "* set Sampler:BinSampler:MaxNewMax N\n\n"
<< "---------------------------------------------------\n"
<< Exception::abortnow;
}
maxweight=w;
k=0;
numlastmax=0;
}
if ( progress ) {
++(*progressBar);
}
}
if ( progress ) {
Repository::clog() << "integrated ( " << ANSI::yellow
<< averageWeight() << " +/- " << sqrt(averageWeightVariance())
<< ANSI::reset << " ) nb\nepsilon = "
<< (abs(maxWeight()) != 0. ? averageAbsWeight()/abs(maxWeight()) : 0.);
if ( !iterations().empty() )
Repository::clog() << " chi2 = " << chi2();
Repository::clog() << "\n";
Repository::clog() << "---------------------------------------------------\n";
}
if ( progressBar )
delete progressBar;
}
void BinSampler::initialize(bool progress) {
lastPoint().resize(dimension());
if (randomNumberString()!="")
for(size_t i=0;i<lastPoint().size();i++){
RandomNumberHistograms[RandomNumberIndex(id(),i)] = make_pair( RandomNumberHistogram(),0.);
}
if ( initialized() )
return;
if ( !sampler()->grids().children().empty() ) {
nIterations(1);
}
if ( !integrated() ) {
unsigned long points = initialPoints();
for ( unsigned long k = 0; k < nIterations(); ++k ) {
runIteration(points,progress);
if ( k < nIterations() - 1 ) {
points = (unsigned long)(points*enhancementFactor());
adapt();
nextIteration();
}
}
}
isInitialized();
}
void BinSampler::finalize(bool){
if (theRandomNumbers!="")
for ( map<RandomNumberIndex,pair<RandomNumberHistogram,double> >::
const_iterator b = RandomNumberHistograms.begin();
b != RandomNumberHistograms.end(); ++b ) {
b->second.first.dump(randomNumberString(), b->first.first,shortprocess(),b->first.second);
}
}
BinSampler::RandomNumberHistogram::
RandomNumberHistogram(double low,
double up,
unsigned int nbins)
: lower(low) {
nbins = nbins + 1;
double c = up / (nbins-1.);
for ( unsigned int k = 1; k < nbins; ++k ) {
bins[low+c*k] = 0.;
binsw1[low+c*k] = 0.;
}
}
void BinSampler::RandomNumberHistogram::
dump(const std::string& folder,const std::string& prefix, const std::string& process,
const int NR) const {
ostringstream fname("");
std::string prefix2;
std::string prefix3=prefix;
std::remove_copy(prefix.begin(), prefix.end(), std::back_inserter(prefix2), '.');
prefix3=prefix2;prefix2.clear();
std::remove_copy(prefix3.begin(), prefix3.end(), std::back_inserter(prefix2), ':');
prefix3=prefix2;prefix2.clear();
std::remove_copy(prefix3.begin(), prefix3.end(), std::back_inserter(prefix2), ',');
fname << "RN-"<< NR ;
ofstream out((folder+"/"+prefix2+fname.str()+".dat").c_str());
double sumofweights=0.;
for ( map<double,double >::const_iterator b = bins.begin();b != bins.end(); ++b )
sumofweights+=b->second;
double sumofweights2=0.;
for ( map<double,double >::const_iterator b = binsw1.begin();b != binsw1.end(); ++b )
sumofweights2+=b->second;
map<double,double >::const_iterator b2 = binsw1.begin();
if ( sumofweights == 0 ) {
cerr << "Not enough statistic accumulated for "
<< process << " skipping random number diagnostic.\n"
<< flush;
return;
}
for ( map<double,double >::const_iterator b = bins.begin();
b != bins.end(); ++b, ++b2) {
out << " " << b->first
<< " " << b->second/sumofweights*100.
<< " " << b2->second/sumofweights2*100.
<< "\n" << flush;
}
double xmin = -0.01;
double xmax = 1.01;
ofstream gpout((folder+"/"+prefix2+fname.str()+".gp").c_str());
gpout << "set terminal epslatex color solid\n"
<< "set output '" << prefix2+fname.str() << "-plot.tex'\n"
<< "set xrange [" << xmin << ":" << xmax << "]\n";
gpout << "set xlabel 'rn "<<NR <<"' \n";
gpout << "set size 0.5,0.6\n";
gpout << "plot '" << prefix2+fname.str()
<< ".dat' u ($1):($2) w boxes lc rgbcolor \"blue\" t '{\\tiny "<<process <<" }',";
gpout << " '" << prefix2+fname.str();
gpout << ".dat' u ($1):($3) w boxes lc rgbcolor \"red\" t '';";
gpout << "reset\n";
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void BinSampler::persistentOutput(PersistentOStream & os) const {
MultiIterationStatistics::put(os);
os << theBias << theWeighted << theInitialPoints << theNIterations
<< theEnhancementFactor << theNonZeroInPresampling << theHalfPoints
<< theMaxNewMax << theReferenceWeight
<< theBin << theInitialized << theLastPoint
<< theEventHandler << theSampler << theRandomNumbers
<< theRemapperPoints << theRemapChannelDimension
<< theLuminosityMapperBins << theGeneralMapperBins << theKappa;
}
void BinSampler::persistentInput(PersistentIStream & is, int) {
MultiIterationStatistics::get(is);
is >> theBias >> theWeighted >> theInitialPoints >> theNIterations
>> theEnhancementFactor >> theNonZeroInPresampling >> theHalfPoints
>> theMaxNewMax >> theReferenceWeight
>> theBin >> theInitialized >> theLastPoint
>> theEventHandler >> theSampler >> theRandomNumbers
>> theRemapperPoints >> theRemapChannelDimension
>> theLuminosityMapperBins >> theGeneralMapperBins >> theKappa;
}
// *** 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<BinSampler,MultiIterationStatistics>
describeHerwigBinSampler("Herwig::BinSampler", "HwSampling.so");
void BinSampler::Init() {
static ClassDocumentation<BinSampler> documentation
("BinSampler samples XCombs bins. This default implementation performs flat MC integration.");
static Parameter<BinSampler,unsigned long> interfaceInitialPoints
("InitialPoints",
"The number of points to use for initial integration.",
&BinSampler::theInitialPoints, 1000000, 1, 0,
false, false, Interface::lowerlim);
static Parameter<BinSampler,size_t> interfaceNIterations
("NIterations",
"The number of iterations to perform initially.",
&BinSampler::theNIterations, 1, 1, 0,
false, false, Interface::lowerlim);
static Parameter<BinSampler,double> interfaceEnhancementFactor
("EnhancementFactor",
"The enhancement factor for the number of points in the next iteration.",
&BinSampler::theEnhancementFactor, 2.0, 1.0, 0,
false, false, Interface::lowerlim);
static Switch<BinSampler,bool> interfaceNonZeroInPresampling
("NonZeroInPresampling",
"Switch on to count only non zero weights in presampling.",
&BinSampler::theNonZeroInPresampling, true, false, false);
static SwitchOption interfaceNonZeroInPresamplingYes
(interfaceNonZeroInPresampling,
"Yes",
"",
true);
static SwitchOption interfaceNonZeroInPresamplingNo
(interfaceNonZeroInPresampling,
"No",
"",
false);
static Switch<BinSampler,bool> interfaceHalfPoints
("HalfPoints",
"Switch on to reset the counter of points if new maximumis was found in the first 1/2 points.",
&BinSampler::theHalfPoints, true, false, false);
static SwitchOption interfaceHalfPointsYes
(interfaceHalfPoints,
"Yes",
"",
true);
static SwitchOption interfaceHalfPointsNo
(interfaceHalfPoints,
"No",
"",
false);
static Parameter<BinSampler,int> interfaceMaxNewMax
("MaxNewMax",
"The maximum number of allowed new maxima in combination with the HalfPoints option.",
&BinSampler::theMaxNewMax, 30, 1, 0,
false, false, Interface::lowerlim);
static Parameter<BinSampler,string> interfaceRandomNumbers
("RandomNumbers",
"Prefix for distributions of the random numbers.",
&BinSampler::theRandomNumbers, "",
false, false);
static Parameter<BinSampler,unsigned long> interfaceRemapperPoints
("RemapperPoints",
"The number of points to be used for filling remappers.",
&BinSampler::theRemapperPoints, 10000, 0, 0,
false, false, Interface::lowerlim);
static Switch<BinSampler,bool> interfaceRemapChannelDimension
("RemapChannelDimension",
"Switch on remapping of the channel dimension.",
&BinSampler::theRemapChannelDimension, true, false, false);
static SwitchOption interfaceRemapChannelDimensionYes
(interfaceRemapChannelDimension,
"Yes",
"",
true);
static SwitchOption interfaceRemapChannelDimensionNo
(interfaceRemapChannelDimension,
"No",
"",
false);
static Parameter<BinSampler,unsigned long> interfaceLuminosityMapperBins
("LuminosityMapperBins",
"The number of bins to be used for remapping parton luminosities.",
&BinSampler::theLuminosityMapperBins, 0, 0, 0,
false, false, Interface::lowerlim);
static Parameter<BinSampler,unsigned long> interfaceGeneralMapperBins
("GeneralMapperBins",
"The number of bins to be used for remapping other phase space dimensions.",
&BinSampler::theGeneralMapperBins, 0, 0, 0,
false, false, Interface::lowerlim);
static Parameter<BinSampler,double> interfaceRemapperMinSelection
("RemapperMinSelection",
"The minimum bin selection probability for remappers.",
&BinSampler::theRemapperMinSelection, 0.00001, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<BinSampler,double> interfaceKappa
("Kappa",
"In AllmostUnweighted mode unweight to Kappa ReferenceWeight.",
&BinSampler::theKappa, 1., 0.000001, 1.0,
false, false, Interface::limited);
}
diff --git a/Sampling/BinSampler.h b/Sampling/BinSampler.h
--- a/Sampling/BinSampler.h
+++ b/Sampling/BinSampler.h
@@ -1,592 +1,584 @@
// -*- C++ -*-
//
// BinSampler.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef Herwig_BinSampler_H
#define Herwig_BinSampler_H
//
// This is the declaration of the BinSampler class.
//
#include "ThePEG/Handlers/StandardEventHandler.h"
#include "ThePEG/Utilities/Exception.h"
#include "ThePEG/Repository/UseRandom.h"
#include "MultiIterationStatistics.h"
#include "Remapper.h"
namespace Herwig {
using namespace ThePEG;
class GeneralSampler;
/**
* \ingroup Matchbox
* \author Simon Platzer
*
* \brief BinSampler samples XCombs bins. This default implementation
* performs flat MC integration.
*
* @see \ref BinSamplerInterfaces "The interfaces"
* defined for BinSampler.
*/
class BinSampler: public Herwig::MultiIterationStatistics {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
BinSampler();
- /**
- * The destructor.
- */
- virtual ~BinSampler();
- //@}
-
public:
/**
* Clone this object.
*/
Ptr<BinSampler>::ptr cloneMe() const {
return dynamic_ptr_cast<Ptr<BinSampler>::ptr>(clone());
}
public:
/**
* Evaluate the cross section
*/
double evaluate(vector<double> p,
bool remap = true);
/**
* Return the bias with which this sampler is selected. The sampler
* needs to divide out this bias in its weight calculation.
*/
double bias() const { return theBias; }
/**
* Set the bias with which this sampler is selected.
*/
void bias(double b) { theBias = b; }
/**
* Set the event handler
*/
void eventHandler(tStdEHPtr eh) { theEventHandler = eh; }
/**
* Return the event handler
*/
tStdEHPtr eventHandler() const { return theEventHandler; }
/**
* Set the containing sampler
*/
void sampler(Ptr<GeneralSampler>::tptr);
/**
* Get the containing sampler
*/
Ptr<GeneralSampler>::tptr sampler() const;
/**
* Return the bin
*/
int bin() const { return theBin; }
/**
* Set the bin
*/
void bin(int b) { theBin = b; }
/**
* Return a string describing the process handled by this sampler.
*/
string process() const;
/**
* Return a short string describing the process handled by this sampler.
*/
string shortprocess() const;
/**
* Return a string identifying the process handled by this sampler.
*/
string id() const;
/**
* Return the last generated point.
*/
const vector<double>& lastPoint() const { return theLastPoint; }
/**
* Access the last generated point.
*/
vector<double>& lastPoint() { return theLastPoint; }
/**
* Return the reference weight to be used
*/
double referenceWeight() const { return theReferenceWeight; }
/**
* Set the reference weight to be used
*/
void referenceWeight(double w) { theReferenceWeight = w; }
/**
* Return true, if this sampler can provide unweighted events; if
* the proposal density is not an overestimate, weights larger than
* one can be generated, the handling of these points being subject
* to the GeneralSampler class.
*/
virtual bool canUnweight() const { return true; }
/**
* Return true, if this sampler adapts on the fly while generating
* events. Cross sections in the GeneralSampler class are calculated
* from adding up the cross sections quoted by individual samplers.
*/
virtual bool adaptsOnTheFly() const { return false; }
/**
* If this sampler features a compensation algorithm, return true if
* more events need to be generated to finish the compensation.
*/
virtual bool compensating() const { return false; }
/**
* Return true, if weighted events should be generated
*/
bool weighted() const { return theWeighted; }
/**
* Indicate that weighted events should be generated
*/
void doWeighted(bool yes = true) { theWeighted = yes; }
/**
* Exception to be thrown if cross section information should be updated.
*/
struct NextIteration {};
/**
* Generate the next point and return its weight; store the point in
* lastPoint().
*/
virtual double generate();
/**
* Fill and finalize the remappers present
*/
void fillRemappers(bool progress);
/**
* Write remappers to grid file
*/
void saveRemappers() const;
/**
* Write integration data to grid files
*/
void saveIntegrationData() const;
/**
* Save grid data
*/
virtual void saveGrid() const {}
/**
* Read integration data from grid files
*/
void readIntegrationData();
/**
* Read remappers from grid file
*/
void setupRemappers(bool progress);
/**
* Run a single iteration of n points, optionally printing a
* progress bar to cout. Calls generate n times.
*/
void runIteration(unsigned long n, bool progress);
/**
* Adapt this sampler after an iteration has been run
*/
virtual void adapt() {}
/**
* Initialize this bin sampler. This default version calls runIteration.
*/
virtual void initialize(bool progress);
/**
* Return true, if this sampler has already been initialized.
*/
bool initialized() const { return theInitialized; }
/**
* Indicate that this sampler has already been initialized.
*/
void isInitialized() { theInitialized = true; }
/**
* Return true, if integration has already been performed
*/
bool integrated() const { return theIntegrated; }
/**
* Return true, if remappers have been set up
*/
bool remappersFilled() const { return theRemappersFilled; }
/**
* Return true, if grid data exists for this sampler.
*/
virtual bool existsGrid() const { return false; }
/**
* Return true, if this sampler has already read grid data.
*/
bool hasGrids() const { return theHasGrids; }
/**
* Indicate that this sampler has already read grid data.
*/
void didReadGrids() { theHasGrids = true; }
/**
* Finalize this sampler.
*/
virtual void finalize(bool);
/**
* Return the total integrated cross section determined from the
* Monte Carlo sampling so far.
*/
virtual CrossSection integratedXSec() const {
return averageWeight()*nanobarn;
}
/**
* Return the error on the total integrated cross section determined
* from the Monte Carlo sampling so far.
*/
virtual CrossSection integratedXSecErr() const {
return sqrt(abs(averageWeightVariance()))*nanobarn;
}
/**
* Define the key for the collinear subtraction data.
*/
struct RandomNumberHistogram {
/**
* The lower bound
*/
double lower;
/**
* The bins, indexed by upper bound.
*/
map<double,double > bins;
map<double,double > binsw1;
/**
* Constructor
*/
RandomNumberHistogram(double low = 0.0,
double up = 1.,
unsigned int nbins = 20);
/**
* Book an event.
*/
void book(double inv, double weight) {
map<double,double>::iterator b = bins.upper_bound(inv);
if ( b == bins.end() ) return;
b->second = b->second+weight;
map<double,double>::iterator b2 = binsw1.upper_bound(inv);
if ( b2 == binsw1.end() ) return;
b2->second = b2->second+1.;
}
/**
* Write to file given name and invariant.
*/
void dump(const std::string& folder,const std::string& prefix, const std::string& process,const int NR)const;
};
typedef pair<string,size_t > RandomNumberIndex;
map<RandomNumberIndex,pair<RandomNumberHistogram,double> > RandomNumberHistograms;
public:
/**
* Return the dimension.
*/
int dimension() const { return theEventHandler->nDim(bin()); }
/**
* Return the number of points to be used for initial integration.
*/
unsigned long initialPoints() const { return theInitialPoints; }
/**
* Set the number of points to be used for initial integration.
*/
void initialPoints(unsigned long n) { theInitialPoints = n; }
/**
* Return the number of iterations to be considered for initialization.
*/
size_t nIterations() const { return theNIterations; }
/**
* Set the number of iterations to be considered for initialization.
*/
void nIterations(size_t n) { theNIterations = n; }
/**
* Set the factor to enhance the number of points for the next
* iteration.
*/
void enhancementFactor(double f) { theEnhancementFactor = f; }
/**
* Return the factor to enhance the number of points for the next
* iteration.
*/
double enhancementFactor() const { return theEnhancementFactor; }
/**
* Return the folder for the random number plots.
*/
string randomNumberString() const {return theRandomNumbers;}
/**
* In the AlmostUnweighted mode we do not need to unweight
* the events to the reference weight.
* Kappa reduces effectivly the reference weight.
* This can be used for processes, where unweighting
* is hardly feasable.
*/
double kappa() const {return theKappa;}
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 bias with which this sampler is selected.
*/
double theBias;
/**
* True, if weighted events should be generated
*/
bool theWeighted;
/**
* The number of points to use for initial integration.
*/
unsigned long theInitialPoints;
/**
* The number of iterations to be considered for initialization.
*/
size_t theNIterations;
/**
* Factor to enhance the number of points for the next iteration.
*/
double theEnhancementFactor;
/**
* Switch to count only non zero weights in presampling.
*/
bool theNonZeroInPresampling;
/**
* Switch to require that we get half of the points
* in each iteration below the maximum weight of the iteration.
*/
bool theHalfPoints;
/**
* The maximum number of allowed new maxima,
* in combination with HalfPoints, in order to prevent unstable
* processes.
*/
int theMaxNewMax;
/**
* The reference weight to be used
*/
double theReferenceWeight;
/**
* The bin to be sampled.
*/
int theBin;
/**
* Wether or not this sampler has already been initialized.
*/
bool theInitialized;
/**
* The last generated point.
*/
vector<double> theLastPoint;
/**
* The event handler to be used.
*/
tStdEHPtr theEventHandler;
/**
* The containing sampler
*/
Ptr<GeneralSampler>::tptr theSampler;
/**
* Folder for the random number plots.
*/
string theRandomNumbers;
/**
* Remapper objects indexed by dimension
*/
map<size_t,Remapper> remappers;
/**
* The number of points to be used for initial filling of the remappers
*/
unsigned long theRemapperPoints;
/**
* True if channels should get a remapper
*/
bool theRemapChannelDimension;
/**
* The number of bins to be used for luminosity dimensions
*/
unsigned long theLuminosityMapperBins;
/**
* The number of bins to be used for any other dimension
*/
unsigned long theGeneralMapperBins;
/**
* The minimum selection probability for remapper bins
*/
double theRemapperMinSelection;
/**
* True, if integration has already be performed
*/
bool theIntegrated;
/**
* True, if remappers have been set up
*/
bool theRemappersFilled;
/**
* True, if this sampler has already read grid data.
*/
bool theHasGrids;
/**
* In the AlmostUnweighted mode we do not need to unweight
* the events to the reference weight.
* Kappa reduces effectivly the reference weight.
* This can be used for processes, where unweighting
* is hardly feasable.
*/
double theKappa;
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
BinSampler & operator=(const BinSampler &) = delete;
};
}
#endif /* Herwig_BinSampler_H */
diff --git a/Shower/Dipole/AlphaS/alpha_s.cc b/Shower/Dipole/AlphaS/alpha_s.cc
--- a/Shower/Dipole/AlphaS/alpha_s.cc
+++ b/Shower/Dipole/AlphaS/alpha_s.cc
@@ -1,236 +1,234 @@
// -*- C++ -*-
// couplings/alpha_s.cc is part of matchbox
// (C) 2008 Simon Platzer -- sp@particle.uni-karlsruhe.de
#include "alpha_s.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/Repository.h"
#include "ThePEG/PDT/ParticleData.h"
using namespace matchbox;
alpha_s::alpha_s()
: AlphaSBase(), min_active_flavours_(3), max_active_flavours_(6),
matched_(false), scale_factor_(1.), quark_masses_squared_(),
lambda_squared_(), alpha_s_in_(.1176), scale_in_(91.1876*GeV),
lambda_range_(1.*MeV2,1.e6*MeV2), fixed_(false) {
}
-alpha_s::~alpha_s() {}
-
void alpha_s::persistentOutput(PersistentOStream & os) const {
os << min_active_flavours_ << max_active_flavours_ << matched_ << scale_factor_;
for (size_t f = 0; f < 7; ++f)
os << ounit(quark_masses_squared_[f],MeV2)
<< ounit(lambda_squared_[f],MeV2);
for (size_t f = 0; f < 6; ++f)
os << ounit(nfvector[f],MeV2);
os << alpha_s_in_ << ounit(scale_in_,GeV)
<< ounit(lambda_range_.first,MeV2) << ounit(lambda_range_.second,MeV2)
<< fixed_;
}
void alpha_s::persistentInput(PersistentIStream & is, int) {
is >> min_active_flavours_ >> max_active_flavours_ >> matched_ >> scale_factor_;
for (size_t f = 0; f < 7; ++f)
is >> iunit(quark_masses_squared_[f],MeV2)
>> iunit(lambda_squared_[f],MeV2);
for (size_t f = 0; f < 6; ++f)
is >> iunit(nfvector[f],MeV2);
is >> alpha_s_in_ >> iunit(scale_in_,GeV)
>> iunit(lambda_range_.first,MeV2) >> iunit(lambda_range_.second,MeV2)
>> fixed_;
}
AbstractClassDescription<alpha_s> alpha_s::initalpha_s;
// Definition of the static class description member.
void alpha_s::Init() {
static ClassDocumentation<alpha_s> documentation
("Base class for strong coupoling as used in matchbox");
static Parameter<alpha_s,unsigned int> interfacemin_active_flavours
("min_active_flavours",
"Minimum number of active flavours",
&alpha_s::min_active_flavours_, 3, 0, 6,
true, false, Interface::limited);
static Parameter<alpha_s,unsigned int> interfacemax_active_flavours
("max_active_flavours",
"Maximum number of active flavours",
&alpha_s::max_active_flavours_, 6, 0, 6,
true, false, Interface::limited);
static Parameter<alpha_s,double> interfaceinput_alpha_s
("input_alpha_s",
"alpha_s value at input scale",
&alpha_s::alpha_s_in_, .1176, 0.0, 1.0,
true, false, Interface::limited);
static Parameter<alpha_s,Energy> interfaceinput_scale
("input_scale",
"Input scale for alpha_s value",
&alpha_s::scale_in_, GeV, 91.1876*GeV, 0.*GeV, 0.*GeV,
true, false, Interface::lowerlim);
static Command<alpha_s> interfacecheck
("check",
"check",
&alpha_s::check, false);
static Parameter<alpha_s,double> interfacescale_factor
("scale_factor",
"scale factor for argument",
&alpha_s::scale_factor_, 1., 0.0, 100.0,
true, false, Interface::limited);
static Switch<alpha_s,bool> interfacefixed
("fixed",
"",
&alpha_s::fixed_, false, false, false);
static SwitchOption interfacefixedYes
(interfacefixed,
"Yes",
"",
true);
static SwitchOption interfacefixedNo
(interfacefixed,
"No",
"",
false);
}
string alpha_s::check (string args) {
istringstream argin(args);
double Q_low, Q_high;
long n_steps;
argin >> Q_low >> Q_high >> n_steps;
string fname;
argin >> fname;
Repository::clog() << "checking alpha_s in range [" << Q_low << "," << Q_high << "] GeV in "
<< n_steps << " steps.\nResults are written to " << fname << "\n";
double step_width = (Q_high-Q_low)/n_steps;
match_thresholds();
Repository::clog() << "threshold matching results:\n"
<< "(m_Q^2 -> Lambda^2) / GeV^2 for dynamic flavours in range ["
<< min_active_flavours_ << "," << max_active_flavours_ << "]\n";
for (size_t f = 0; f < 7; ++f) {
Repository::clog() << (quark_masses_squared_[f]/GeV2) << " "
<< (lambda_squared_[f]/GeV2) << "\n";
}
ofstream out (fname.c_str());
for (long k = 0; k <= n_steps; ++k) {
Energy Q = Q_low*GeV + k*step_width*GeV;
out << (Q/GeV) << " " << (operator () (Q*Q)) << "\n";
}
return "alpha_s check finished";
}
void alpha_s::match_thresholds () {
if (matched_)
return;
// get the quark masses
quark_masses_squared_[0] = 0.*MeV2;
for (long f = 1; f < 7; ++f) {
if ( quarkMasses().empty() )
quark_masses_squared_[static_cast<size_t>(f)]
= sqr(getParticleData(f)->mass());
else
quark_masses_squared_[static_cast<size_t>(f)]
= sqr(quarkMasses()[static_cast<size_t>(f-1)]);
}
if ( quark_masses_squared_[1] > quark_masses_squared_[2] )
swap(quark_masses_squared_[1],quark_masses_squared_[2]);
unsigned int active_at_input = active_flavours(sqr(scale_in_));
// solve for input lambda
solve_input_lambda<alpha_s> input_equation (this,active_at_input,alpha_s_in_,sqr(scale_in_));
gsl::bisection_root_solver<solve_input_lambda<alpha_s>,100> input_solver(input_equation);
lambda_squared_[active_at_input] =
MeV2 *
input_solver.solve({lambda_range_.first/MeV2,lambda_range_.second/MeV2});
// get lambdas down to min active flavours
unsigned int below = active_at_input;
while (below > min_active_flavours_) {
solve_lambda_below<alpha_s> match_equation (this,below,
lambda_squared_[below],
quark_masses_squared_[below]);
gsl::bisection_root_solver<solve_lambda_below<alpha_s>,100> match_solver(match_equation);
lambda_squared_[below-1] =
MeV2 *
match_solver.solve({lambda_range_.first/MeV2,lambda_range_.second/MeV2});
--below;
}
// get lambdas up to max active flavours
unsigned int above = active_at_input;
while (above < max_active_flavours_) {
solve_lambda_above<alpha_s> match_equation (this,above,
lambda_squared_[above],
quark_masses_squared_[above+1]);
gsl::bisection_root_solver<solve_lambda_above<alpha_s>,100> match_solver(match_equation);
lambda_squared_[above+1] =
MeV2 *match_solver.solve({lambda_range_.first/MeV2,lambda_range_.second/MeV2});
++above;
}
if (min_active_flavours_ > 0) {
for (size_t f = 0; f < min_active_flavours_; ++f) {
lambda_squared_[f] = lambda_squared_[min_active_flavours_];
}
}
if (max_active_flavours_ < 6) {
for (size_t f = max_active_flavours_+1; f < 7; ++f) {
lambda_squared_[f] = lambda_squared_[max_active_flavours_];
}
}
matched_ = true;
return;
}
diff --git a/Shower/Dipole/AlphaS/alpha_s.h b/Shower/Dipole/AlphaS/alpha_s.h
--- a/Shower/Dipole/AlphaS/alpha_s.h
+++ b/Shower/Dipole/AlphaS/alpha_s.h
@@ -1,352 +1,344 @@
// -*- C++ -*-
// couplings/alpha_s.h is part of matchbox
// (C) 2008 Simon Platzer -- sp@particle.uni-karlsruhe.de
#ifndef matchbox_couplings_alpha_s_h
#define matchbox_couplings_alpha_s_h
#include <string>
#include <array>
#include "ThePEG/Interface/Interfaced.h"
#include "ThePEG/StandardModel/AlphaSBase.h"
#include "gsl.h"
namespace matchbox {
using namespace ThePEG;
template<class AlphaS>
struct solve_lambda_below {
typedef AlphaS alpha_s;
inline solve_lambda_below (alpha_s* a,
unsigned int n,
Energy2 lambda2n,
Energy2 mass2)
: alpha(a), nf_in(n), lambda2_nf_in(lambda2n), threshold(mass2) {}
alpha_s * alpha;
unsigned int nf_in;
Energy2 lambda2_nf_in;
Energy2 threshold;
inline double operator () (double lambda2) {
return ((*alpha)(threshold,lambda2_nf_in,nf_in) -
(*alpha)(threshold,lambda2*MeV2,nf_in-1));
}
};
template<class AlphaS>
struct solve_lambda_above {
typedef AlphaS alpha_s;
inline solve_lambda_above (alpha_s * a,
unsigned int n,
Energy2 lambda2n,
Energy2 mass2)
: alpha(a), nf_in(n), lambda2_nf_in(lambda2n), threshold(mass2) {}
alpha_s * alpha;
unsigned int nf_in;
Energy2 lambda2_nf_in;
Energy2 threshold;
inline double operator () (double lambda2) {
return ((*alpha)(threshold,lambda2_nf_in,nf_in) -
(*alpha)(threshold,lambda2*MeV2,nf_in+1));
}
};
template<class AlphaS>
struct solve_input_lambda {
typedef AlphaS alpha_s;
inline solve_input_lambda (alpha_s * a,
unsigned int n,
double inalpha,
Energy2 inscale)
: alpha(a), nf_in(n), alpha_in(inalpha), scale_in(inscale) {}
alpha_s * alpha;
unsigned int nf_in;
double alpha_in;
Energy2 scale_in;
inline double operator () (double lambda2) {
return ((*alpha)(scale_in,lambda2*MeV2,nf_in) - alpha_in);
}
};
/**
* Base class for the strong coupling.
*
* @see \ref alpha_sInterfaces "The interfaces"
* defined for alpha_s.
*/
class alpha_s
: public AlphaSBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
alpha_s();
-
- /**
- * The destructor.
- */
- virtual ~alpha_s();
- //@}
public:
/** @name Virtual functions as required by AlphaSBase. */
//@{
/**
* The \f$\alpha_S\f$. Return the QCD coupling for a given \a scale
* using the given standard model object \a sm.
*/
virtual inline double value(Energy2 scale, const StandardModelBase &) const {
return operator() (scale);
}
/**
* Return the flavour thresholds used. The returned vector contains
* (in position <code>i</code>) the scales when the active number of
* flavours changes from <code>i</code> to <code>i+1</code>.
*/
virtual inline vector<Energy2> flavourThresholds() const {
assert(!nfvector.empty());
return nfvector;
}
/**
* Return the \f$\Lambda_{QCD}\f$ used for different numbers of
* active flavours.
*/
virtual inline vector<Energy> LambdaQCDs() const {
vector<Energy> res;
for (size_t k = 0; k < 7; ++k)
res.push_back(sqrt(lambda_squared_[k]));
return res;
}
//@}
public:
/// return alpha_s as function of scale
inline double operator () (Energy2 scale) const {
if ( fixed_ )
return alpha_s_in_;
assert(matched());
unsigned int active = active_flavours(scale_factor_*scale);
return operator () (scale_factor_*scale,lambda_squared_[active],active);
}
/// return alpha_s as function of scale, QCD scale
/// and number of active flavours
virtual double operator () (Energy2 scale,
Energy2 lambda2,
unsigned int nf) const = 0;
/// match thresholds and write alpha_s
/// to specified file; arguments are
/// Q_low/GeV Q_high/GeV n_steps filename
string check (string args);
public:
/// return minimum number of active flavours
inline unsigned int min_active_flavours () const { return min_active_flavours_; }
/// set minimum number of active flavours
inline void min_active_flavours (unsigned int nf) { min_active_flavours_ = nf; }
/// return maximum number of active flavours
inline unsigned int max_active_flavours () const { return max_active_flavours_; }
/// set maximum number of active flavours
inline void max_active_flavours (unsigned int nf) { max_active_flavours_ = nf; }
/// return the number of active flavours at the given scale
inline unsigned int active_flavours (Energy2 scale) const {
unsigned int active = 0;
if (scale > 0.*GeV2) {
while(quark_mass_squared(active) < scale) {
if (++active == max_active_flavours_+1)
break;
}
active -= 1;
} else {
active = 0;
}
return active;
}
/// return the lambda squared for the given number of flavours
inline Energy2 lambda_squared (unsigned int f) const {
assert(f < 7);
return lambda_squared_[f];
}
/// return the mass squared for given flavour
inline Energy2 quark_mass_squared (unsigned int f) const {
assert(f < 7);
return quark_masses_squared_[f];
}
/// set the mass squared for given flavour
inline void quark_mass_squared (unsigned int f, Energy2 m2) {
assert(f < 7);
quark_masses_squared_[f] = m2;
matched_ = false;
}
public:
/// perform the threshold matching
/// given alpha_s value at reference scale
void match_thresholds ();
/// return true, if threshold matching has been
/// performed
inline bool matched () const { return matched_; }
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 inline void doinit() {
match_thresholds();
copy(quark_masses_squared_.begin()+1,
quark_masses_squared_.end(),nfvector.begin());
AlphaSBase::doinit();
}
//@}
/// return the scale factor
double scale_factor () const { return scale_factor_; }
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @name os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @name is the persistent input stream read from.
* @name 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();
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is an abstract class with persistent data.
*/
static AbstractClassDescription<alpha_s> initalpha_s;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
alpha_s & operator=(const alpha_s &) = delete;
private:
unsigned int min_active_flavours_;
unsigned int max_active_flavours_;
bool matched_;
double scale_factor_;
std::array<Energy2,7> quark_masses_squared_;
std::array<Energy2,7> lambda_squared_;
vector<Energy2> nfvector=vector<Energy2>(6);
double alpha_s_in_;
Energy scale_in_;
pair<Energy2,Energy2> lambda_range_;
bool fixed_;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of alpha_s. */
template <>
struct BaseClassTrait<matchbox::alpha_s,1> {
/** Typedef of the first base class of alpha_s. */
typedef AlphaSBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the alpha_s class and the shared object where it is defined. */
template <>
struct ClassTraits<matchbox::alpha_s>
: public ClassTraitsBase<matchbox::alpha_s> {
/** Return a platform-independent class name */
static string className() { return "matchbox::alpha_s"; }
/**
* The name of a file containing the dynamic library where the class
* alpha_s is implemented. It may also include several, space-separated,
* libraries if the class alpha_s 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 "HwDipoleShowerAlphaS.so"; }
};
/** @endcond */
}
#endif /* matchbox_couplings_alpha_s_h */
diff --git a/Shower/Dipole/AlphaS/lo_alpha_s.cc b/Shower/Dipole/AlphaS/lo_alpha_s.cc
--- a/Shower/Dipole/AlphaS/lo_alpha_s.cc
+++ b/Shower/Dipole/AlphaS/lo_alpha_s.cc
@@ -1,67 +1,65 @@
// -*- C++ -*-
// couplings/lo_alpha_s.cc is part of matchbox
// (C) 2008 Simon Platzer -- sp@particle.uni-karlsruhe.de
#include "lo_alpha_s.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace matchbox;
lo_alpha_s::lo_alpha_s()
: alpha_s(), freezing_scale_(1.*GeV) {}
-lo_alpha_s::~lo_alpha_s() {}
-
IBPtr lo_alpha_s::clone() const {
return new_ptr(*this);
}
IBPtr lo_alpha_s::fullclone() const {
return new_ptr(*this);
}
void lo_alpha_s::persistentOutput(PersistentOStream & os) const {
os << ounit(freezing_scale_,GeV);
}
void lo_alpha_s::persistentInput(PersistentIStream & is, int) {
is >> iunit(freezing_scale_,GeV);
}
ClassDescription<lo_alpha_s> lo_alpha_s::initlo_alpha_s;
// Definition of the static class description member.
void lo_alpha_s::Init() {
static ClassDocumentation<lo_alpha_s> documentation
("LO running alpha_s");
static Parameter<lo_alpha_s,Energy> interfacefreezing_scale
("freezing_scale",
"Freeze alpha_s below given scale",
&lo_alpha_s::freezing_scale_, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
true, false, Interface::lowerlim);
}
double lo_alpha_s::operator () (Energy2 scale,
Energy2 lambda2,
unsigned int nf) const {
if (scale < sqr(freezing_scale_)) {
scale = sqr(freezing_scale_);
nf = active_flavours(scale);
lambda2 = lambda_squared(nf);
}
double beta0 = (33.-2.*nf)/(12.*Constants::pi);
return 1./(beta0*log(scale/lambda2));
}
diff --git a/Shower/Dipole/AlphaS/lo_alpha_s.h b/Shower/Dipole/AlphaS/lo_alpha_s.h
--- a/Shower/Dipole/AlphaS/lo_alpha_s.h
+++ b/Shower/Dipole/AlphaS/lo_alpha_s.h
@@ -1,167 +1,159 @@
// -*- C++ -*-
// couplings/lo_alpha_s.h is part of matchbox
// (C) 2008 Simon Platzer -- sp@particle.uni-karlsruhe.de
#ifndef matchbox_couplings_lo_alpha_s_h
#define matchbox_couplings_lo_alpha_s_h
#include "alpha_s.h"
namespace matchbox {
using namespace ThePEG;
/**
* LO running alpha_s
*
* @see \ref lo_alpha_sInterfaces "The interfaces"
* defined for lo_alpha_s.
*/
class lo_alpha_s
: public alpha_s {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
lo_alpha_s();
- /**
- * The destructor.
- */
- virtual ~lo_alpha_s();
- //@}
-
public:
/// return alpha_s as function of scale, QCD scale
/// and number of active flavours
virtual double operator () (Energy2 scale,
Energy2 lambda2,
unsigned int nf) const;
/// return the number of loops which determine this running
virtual unsigned int nloops () const { return 1; }
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @name os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @name is the persistent input stream read from.
* @name 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 inline void doinit() {
freezing_scale_ *= scale_factor();
alpha_s::doinit();
}
//@}
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is an abstract class with persistent data.
*/
static ClassDescription<lo_alpha_s> initlo_alpha_s;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
lo_alpha_s & operator=(const lo_alpha_s &) = delete;
private:
Energy freezing_scale_;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of lo_alpha_s. */
template <>
struct BaseClassTrait<matchbox::lo_alpha_s,1> {
/** Typedef of the first base class of lo_alpha_s. */
typedef matchbox::alpha_s NthBase;
};
/** This template specialization informs ThePEG about the name of
* the lo_alpha_s class and the shared object where it is defined. */
template <>
struct ClassTraits<matchbox::lo_alpha_s>
: public ClassTraitsBase<matchbox::lo_alpha_s> {
/** Return a platform-independent class name */
static string className() { return "matchbox::lo_alpha_s"; }
/**
* The name of a file containing the dynamic library where the class
* lo_alpha_s is implemented. It may also include several, space-separated,
* libraries if the class lo_alpha_s 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 "HwDipoleShowerAlphaS.so"; }
};
/** @endcond */
}
#endif /* matchbox_couplings_lo_alpha_s_h */
diff --git a/Shower/Dipole/AlphaS/nlo_alpha_s.cc b/Shower/Dipole/AlphaS/nlo_alpha_s.cc
--- a/Shower/Dipole/AlphaS/nlo_alpha_s.cc
+++ b/Shower/Dipole/AlphaS/nlo_alpha_s.cc
@@ -1,135 +1,133 @@
// -*- C++ -*-
// couplings/nlo_alpha_s.cc is part of matchbox
// (C) 2008 Simon Platzer -- sp@particle.uni-karlsruhe.de
#include "nlo_alpha_s.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace matchbox;
nlo_alpha_s::nlo_alpha_s()
: alpha_s(), freezing_scale_(1.*GeV),
exact_evaluation_(true), two_largeq_terms_(true) {
}
-nlo_alpha_s::~nlo_alpha_s() {}
-
IBPtr nlo_alpha_s::clone() const {
return new_ptr(*this);
}
IBPtr nlo_alpha_s::fullclone() const {
return new_ptr(*this);
}
void nlo_alpha_s::persistentOutput(PersistentOStream & os) const {
os << ounit(freezing_scale_,GeV) << exact_evaluation_
<< two_largeq_terms_;
}
void nlo_alpha_s::persistentInput(PersistentIStream & is, int) {
is >> iunit(freezing_scale_,GeV) >> exact_evaluation_
>> two_largeq_terms_;
}
ClassDescription<nlo_alpha_s> nlo_alpha_s::initnlo_alpha_s;
// Definition of the static class description member.
void nlo_alpha_s::Init() {
static ClassDocumentation<nlo_alpha_s> documentation
("NLO running alpha_s");
static Parameter<nlo_alpha_s,Energy> interfacefreezing_scale
("freezing_scale",
"Freeze alpha_s below given scale",
&nlo_alpha_s::freezing_scale_, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
true, false, Interface::lowerlim);
static Switch<nlo_alpha_s,bool> interfaceexact_evaluation
("exact_evaluation",
"Wether to exactly evaluate the running or use running for large scales",
&nlo_alpha_s::exact_evaluation_, true, true, false);
static SwitchOption interfaceexact_evaluationexact
(interfaceexact_evaluation,
"exact",
"Perform exact evaluation",
true);
static SwitchOption interfaceexact_evaluationlarge_scale
(interfaceexact_evaluation,
"large_scale",
"Perform approximate evaluation for large scales",
false);
static Switch<nlo_alpha_s,bool> interfacetwo_largeq_terms
("two_largeq_terms",
"Include two terms in the large q expansion.",
&nlo_alpha_s::two_largeq_terms_, true, false, false);
static SwitchOption interfacetwo_largeq_termsYes
(interfacetwo_largeq_terms,
"Yes",
"Include two terms.",
true);
static SwitchOption interfacetwo_largeq_termsNo
(interfacetwo_largeq_terms,
"No",
"Only include one term.",
false);
}
double nlo_alpha_s::operator () (Energy2 scale,
Energy2 lambda2,
unsigned int nf) const {
if (scale < sqr(freezing_scale_)) {
scale = sqr(freezing_scale_);
nf = active_flavours(scale);
lambda2 = lambda_squared(nf);
}
double beta0 = (33.-2.*nf)/(12.*Constants::pi);
double beta1 = (153.-19.*nf)/(24.*sqr(Constants::pi));
if (exact_evaluation_) {
rg_solver().f.slog = log(scale/lambda2);
rg_solver().f.nf = nf;
double slog = rg_solver().f.slog;
double center =
(1./(beta0*slog))*
(1. - (beta1/sqr(beta0)) * log(slog)/slog +
sqr(beta1/(sqr(beta0)*slog)) * (sqr(log(slog)-.5) - 5./4.));
return rg_solver().solve({.5*center,1.5*center});
} else {
double slog = log(scale/lambda2);
double res =
(1./(beta0*slog))*
(1. - (beta1/sqr(beta0)) * log(slog)/slog);
if ( two_largeq_terms_ )
res +=
(1./(beta0*slog))*
(sqr(beta1/(sqr(beta0)*slog)) * (sqr(log(slog)-.5) - 5./4.));
return res;
}
return 0.;
}
diff --git a/Shower/Dipole/AlphaS/nlo_alpha_s.h b/Shower/Dipole/AlphaS/nlo_alpha_s.h
--- a/Shower/Dipole/AlphaS/nlo_alpha_s.h
+++ b/Shower/Dipole/AlphaS/nlo_alpha_s.h
@@ -1,197 +1,189 @@
// -*- C++ -*-
// couplings/nlo_alpha_s.h is part of matchbox
// (C) 2008 Simon Platzer -- sp@particle.uni-karlsruhe.de
#ifndef matchbox_couplings_nlo_alpha_s_h
#define matchbox_couplings_nlo_alpha_s_h
#include "alpha_s.h"
namespace matchbox {
using namespace ThePEG;
/**
* NLO running alpha_s
*
* @see \ref nlo_alpha_sInterfaces "The interfaces"
* defined for nlo_alpha_s.
*/
class nlo_alpha_s
: public alpha_s {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
nlo_alpha_s();
- /**
- * The destructor.
- */
- virtual ~nlo_alpha_s();
- //@}
-
public:
/// return alpha_s as function of scale, QCD scale
/// and number of active flavours
virtual double operator () (Energy2 scale,
Energy2 lambda2,
unsigned int nf) const;
/// return the number of loops which determine this running
virtual unsigned int nloops () const { return 2; }
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @name os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @name is the persistent input stream read from.
* @name 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 inline void doinit() {
freezing_scale_ *= scale_factor();
alpha_s::doinit();
}
//@}
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is an abstract class with persistent data.
*/
static ClassDescription<nlo_alpha_s> initnlo_alpha_s;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
nlo_alpha_s & operator=(const nlo_alpha_s &) = delete;
private:
struct rg_solution {
inline double operator () (double alpha) {
double beta0 = (33.-2.*nf)/(12.*Constants::pi);
double beta1 = (153.-19.*nf)/(24.*sqr(Constants::pi));
return ((1./alpha)+(beta1/beta0)*log(alpha/(beta0+beta1*alpha))- beta0*slog);
}
double slog;
unsigned int nf;
};
Energy freezing_scale_;
bool exact_evaluation_;
static rg_solution& rg () {
static rg_solution rg_;
return rg_;
}
static gsl::bisection_root_solver<rg_solution,100>& rg_solver () {
static gsl::bisection_root_solver<rg_solution,100> rg_solver_(rg());
return rg_solver_;
}
bool two_largeq_terms_;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of nlo_alpha_s. */
template <>
struct BaseClassTrait<matchbox::nlo_alpha_s,1> {
/** Typedef of the first base class of nlo_alpha_s. */
typedef matchbox::alpha_s NthBase;
};
/** This template specialization informs ThePEG about the name of
* the nlo_alpha_s class and the shared object where it is defined. */
template <>
struct ClassTraits<matchbox::nlo_alpha_s>
: public ClassTraitsBase<matchbox::nlo_alpha_s> {
/** Return a platform-independent class name */
static string className() { return "matchbox::nlo_alpha_s"; }
/**
* The name of a file containing the dynamic library where the class
* nlo_alpha_s is implemented. It may also include several, space-separated,
* libraries if the class nlo_alpha_s 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 "HwDipoleShowerAlphaS.so"; }
};
/** @endcond */
}
#endif /* matchbox_couplings_nlo_alpha_s_h */
diff --git a/Shower/Dipole/Base/DipoleChainOrdering.cc b/Shower/Dipole/Base/DipoleChainOrdering.cc
--- a/Shower/Dipole/Base/DipoleChainOrdering.cc
+++ b/Shower/Dipole/Base/DipoleChainOrdering.cc
@@ -1,146 +1,144 @@
// -*- C++ -*-
//
// DipoleChainOrdering.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 DipoleChainOrdering class.
//
#include "DipoleChainOrdering.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
DipoleChainOrdering::DipoleChainOrdering()
: DipoleEvolutionOrdering(), virtualityOrdering(false) {}
-DipoleChainOrdering::~DipoleChainOrdering() {}
-
IBPtr DipoleChainOrdering::clone() const {
return new_ptr(*this);
}
IBPtr DipoleChainOrdering::fullclone() const {
return new_ptr(*this);
}
Energy DipoleChainOrdering::hardScale(tPPtr emitter, tPPtr spectator,
double emitterX, double spectatorX,
const DipoleSplittingKernel& split,
const DipoleIndex& index) const {
Energy scale =
split.splittingKinematics()->dipoleScale(emitter->momentum(),
spectator->momentum());
return
virtualityOrdering ?
split.splittingKinematics()->QMax(scale,emitterX,spectatorX,
index,split,emitter,spectator) :
split.splittingKinematics()->ptMax(scale,emitterX,spectatorX,
index,split,emitter,spectator);
}
void DipoleChainOrdering::setEvolutionScale(Energy scale,
const DipoleSplittingInfo&,
DipoleChain& chain,
pair<list<Dipole>::iterator,list<Dipole>::iterator>) const {
for ( list<Dipole>::iterator dip = chain.dipoles().begin();
dip != chain.dipoles().end(); ++dip ) {
if ( dip->emitterScale({true,false}) > scale )
dip->emitterScale({true,false},scale);
if ( dip->emitterScale({false,true}) > scale )
dip->emitterScale({false,true},scale);
}
}
void DipoleChainOrdering::setEvolutionScale(Energy scale,
const DipoleSplittingInfo&,
DipoleChain& chain,
list<Dipole>::iterator) const {
for ( list<Dipole>::iterator dip = chain.dipoles().begin();
dip != chain.dipoles().end(); ++dip ) {
if ( dip->emitterScale({true,false}) > scale )
dip->emitterScale({true,false},scale);
if ( dip->emitterScale({false,true}) > scale )
dip->emitterScale({false,true},scale);
}
}
Energy DipoleChainOrdering::evolutionScale(const DipoleSplittingInfo& split,
const DipoleSplittingKernel& spkernel) const {
return
virtualityOrdering ?
spkernel.splittingKinematics()->QFromPt(split.lastPt(),split) :
split.lastPt();
}
Energy DipoleChainOrdering::maxPt(Energy scale,
const DipoleSplittingInfo& split,
const DipoleSplittingKernel& spkernel) const {
return
virtualityOrdering ?
spkernel.splittingKinematics()->ptMax(scale,split.emitterX(),split.spectatorX(),split,spkernel) :
scale;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleChainOrdering::persistentOutput(PersistentOStream & os) const {
os << virtualityOrdering;
}
void DipoleChainOrdering::persistentInput(PersistentIStream & is, int) {
is >> virtualityOrdering;
}
ClassDescription<DipoleChainOrdering> DipoleChainOrdering::initDipoleChainOrdering;
// Definition of the static class description member.
void DipoleChainOrdering::Init() {
static ClassDocumentation<DipoleChainOrdering> documentation
("DipoleChainOrdering performs ordering on "
"complete colour singlet dipole chains.");
static Switch<DipoleChainOrdering,bool> interfaceVirtualityOrdering
("Ordering",
"[experimental] Switch between virtuality and pt ordering.",
&DipoleChainOrdering::virtualityOrdering, false, false, false);
static SwitchOption interfaceVirtualityOrderingPt
(interfaceVirtualityOrdering,
"Pt",
"Perform pt ordering",
false);
static SwitchOption interfaceVirtualityOrderingVirtuality
(interfaceVirtualityOrdering,
"Virtuality",
"Perform virtuality ordering",
true);
interfaceVirtualityOrdering.rank(-1);
}
diff --git a/Shower/Dipole/Base/DipoleChainOrdering.h b/Shower/Dipole/Base/DipoleChainOrdering.h
--- a/Shower/Dipole/Base/DipoleChainOrdering.h
+++ b/Shower/Dipole/Base/DipoleChainOrdering.h
@@ -1,200 +1,192 @@
// -*- C++ -*-
//
// DipoleChainOrdering.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_DipoleChainOrdering_H
#define HERWIG_DipoleChainOrdering_H
//
// This is the declaration of the DipoleChainOrdering class.
//
#include "DipoleEvolutionOrdering.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief DipoleChainOrdering performs ordering on
* complete colour singlet dipole chains.
*
*/
class DipoleChainOrdering: public DipoleEvolutionOrdering {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
DipoleChainOrdering();
- /**
- * The destructor.
- */
- virtual ~DipoleChainOrdering();
- //@}
-
public:
/**
* For the given dipole and splitting kernel return
* the hard scale.
*/
virtual Energy hardScale(tPPtr emitter, tPPtr spectator,
double emitterX, double spectatorX,
const DipoleSplittingKernel&,
const DipoleIndex&) const;
/**
* For the given performed splitting, dipole chain
* and dipoles originating from the splitting, set the next
* scale.
*/
virtual void setEvolutionScale(Energy scale,
const DipoleSplittingInfo&,
DipoleChain&,
pair<list<Dipole>::iterator,list<Dipole>::iterator>) const;
/**
* For the given performed splitting, dipole chain
* and dipole taking a recoil, set the next
* scale.
*/
virtual void setEvolutionScale(Energy scale,
const DipoleSplittingInfo&,
DipoleChain&,
list<Dipole>::iterator) const;
/**
* For the given selected splitting return
* the evolution scale.
*/
virtual Energy evolutionScale(const DipoleSplittingInfo& split,
const DipoleSplittingKernel&) const;
/**
* Return the maximum pt corresponding to the given
* evolution scale.
*/
virtual Energy maxPt(Energy scale,
const DipoleSplittingInfo&,
const DipoleSplittingKernel&) 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:
/**
* True, if virtuality instead of pt ordering
* should be performed.
*/
bool virtualityOrdering;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<DipoleChainOrdering> initDipoleChainOrdering;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DipoleChainOrdering & operator=(const DipoleChainOrdering &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of DipoleChainOrdering. */
template <>
struct BaseClassTrait<Herwig::DipoleChainOrdering,1> {
/** Typedef of the first base class of DipoleChainOrdering. */
typedef Herwig::DipoleEvolutionOrdering NthBase;
};
/** This template specialization informs ThePEG about the name of
* the DipoleChainOrdering class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::DipoleChainOrdering>
: public ClassTraitsBase<Herwig::DipoleChainOrdering> {
/** Return a platform-independent class name */
static string className() { return "Herwig::DipoleChainOrdering"; }
/**
* The name of a file containing the dynamic library where the class
* DipoleChainOrdering is implemented. It may also include several, space-separated,
* libraries if the class DipoleChainOrdering 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_DipoleChainOrdering_H */
diff --git a/Shower/Dipole/DipoleShowerHandler.cc b/Shower/Dipole/DipoleShowerHandler.cc
--- a/Shower/Dipole/DipoleShowerHandler.cc
+++ b/Shower/Dipole/DipoleShowerHandler.cc
@@ -1,1906 +1,1904 @@
// -*- C++ -*-
//
// DipoleShowerHandler.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 DipoleShowerHandler class.
//
#include <config.h>
#include "DipoleShowerHandler.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/ParVector.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
// include theses to have complete types
#include "Herwig/PDF/MPIPDF.h"
#include "Herwig/PDF/MinBiasPDF.h"
#include "Herwig/PDF/HwRemDecayer.h"
#include "Herwig/Shower/Dipole/Utility/DipolePartonSplitter.h"
#include "Herwig/MatrixElement/Matchbox/Base/MergerBase.h"
#include "Herwig/MatrixElement/Matchbox/Base/SubtractedME.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
#include <queue>
using namespace Herwig;
bool DipoleShowerHandler::firstWarn = true;
DipoleShowerHandler::DipoleShowerHandler() :
ShowerHandler(), chainOrderVetoScales(true),
nEmissions(0), discardNoEmissions(false), firstMCatNLOEmission(false),
thePowhegDecayEmission(true),
//theAnalyseSpinCorrelations(false),
realignmentScheme(0),
doSubleadingNc(false),subleadingNcEmissionsLimit(0),
densityOperatorEvolution(0),densityOperatorCutoff(1.0*GeV2),
doPartialUnweightingAtEmission(false),
doPartialUnweighting(false),referenceWeight(0.1),
cmecReweightFactor(1.0),negCMECScaling(1.0),
verbosity(0), printEvent(0), nTries(0),
didRadiate(false), didRealign(false),
theRenormalizationScaleFreeze(1.*GeV),
theFactorizationScaleFreeze(2.*GeV), theDoCompensate(false),
theFreezeGrid(500000), theDetuning(1.0),
maxPt(ZERO), muPt(ZERO),
theInputColouredOffShellInShower(),
theZBoundaries(1) {}
-DipoleShowerHandler::~DipoleShowerHandler() {}
-
IBPtr DipoleShowerHandler::clone() const {
return new_ptr(*this);
}
IBPtr DipoleShowerHandler::fullclone() const {
return new_ptr(*this);
}
void DipoleShowerHandler::cascade(tPVector ) {
throw Exception()
<< "DipoleShowerHandler: Dipoleshower not implemented as second shower."
<< "Check your setup or contact Herwig authors."
<< Exception::runerror;
}
tPPair DipoleShowerHandler::cascade(tSubProPtr sub, XCombPtr,
Energy optHardPt, Energy optCutoff) {
useMe();
prepareCascade(sub);
resetWeights();
if ( !doFSR() && ! doISR() )
return sub->incoming();
eventRecord().setSubleadingNc(doSubleadingNc,
subleadingNcEmissionsLimit);
eventRecord().clear();
eventRecord().prepare(sub,dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr()),newStep(),pdfs(),
ShowerHandler::currentHandler()->generator()->currentEvent()->incoming(),
firstInteraction(), offShellPartons(),
!doSubleadingNc);
if ( doSubleadingNc ) {
if ( !theSplittingReweight ) {
throw Exception() << "No splitting reweight was found. "
<< "A ColourMatrixElementCorrection "
<< "splitting reweight is required "
<< "for the subleading colour shower."
<< Exception::runerror;
}
//Set the evolution scheme for the density operator
eventRecord().setDensityOperatorEvolution( densityOperatorEvolution, densityOperatorCutoff );
//Set the CMEC reweight factor
theSplittingReweight->reweightFactor(cmecReweightFactor);
theSplittingReweight->negativeScaling(negCMECScaling);
theSplittingReweight->updateCurrentHandler();
}
// SW: Removed simple test on doFSR and doISR and moved
// here to account for the case of a hard event involving
// no coloured particles but with unstable outgoing particles
if ( !doFSR() && ! doISR() && eventRecord().decays().empty() )
return sub->incoming();
if ( !doISR() &&
eventRecord().outgoing().empty() &&
eventRecord().decays().empty() )
return sub->incoming();
if ( !doFSR() &&
!eventRecord().incoming().first->coloured() &&
!eventRecord().incoming().second->coloured() &&
eventRecord().decays().empty() )
return sub->incoming();
nTries = 0;
// Clear the vertex record for spin correlations
if ( spinCorrelations() ) //|| theAnalyseSpinCorrelations )
vertexRecord().clear();
while ( true ) {
try {
didRadiate = false;
didRealign = false;
if ( eventRecord().truncatedShower() ) {
throw Exception() << "Inconsistent hard emission set-up in DipoleShowerHandler::cascade. "
<< "No truncated shower needed with DipoleShowerHandler. Add "
<< "'set MEMatching:TruncatedShower No' to input file."
<< Exception::runerror;
}
hardScales(lastXCombPtr()->lastShowerScale());
if ( verbosity > 1 ) {
generator()->log() << "DipoleShowerHandler starting off:\n";
eventRecord().debugLastEvent(generator()->log());
generator()->log() << flush;
}
unsigned int nEmitted = 0;
if ( firstMCatNLOEmission ) {
if ( !eventRecord().isMCatNLOHEvent() )
nEmissions = 1;
else
nEmissions = 0;
}
if ( !firstMCatNLOEmission ) {
doCascade(nEmitted,optHardPt,optCutoff);
if ( discardNoEmissions ) {
if ( !didRadiate )
throw Veto();
if ( nEmissions )
if ( nEmissions < nEmitted )
throw Veto();
}
} else {
if ( nEmissions == 1 )
doCascade(nEmitted,optHardPt,optCutoff);
}
if ( intrinsicPtGenerator ) {
if ( eventRecord().incoming().first->coloured() &&
eventRecord().incoming().second->coloured() ) {
LorentzRotation rot =
intrinsicPtGenerator->kick(eventRecord().incoming(),
eventRecord().intermediates());
eventRecord().transform(rot);
}
}
didRealign = realign();
constituentReshuffle();
// backup subleading switch if decays fail
bool doneSubleadingNc = doSubleadingNc;
// subleading N can't handle decays
doSubleadingNc = false;
try {
// Decay and shower any particles that require decaying
while ( !eventRecord().decays().empty() ) {
map<PPtr,PerturbativeProcessPtr>::const_iterator decayIt = eventRecord().decays().begin();
if ( eventRecord().nextDecay() ) {
decayIt = eventRecord().decays().find(eventRecord().nextDecay() );
}
else {
// find the decay to do, one with greatest width and parent showered
while(find(eventRecord().outgoing().begin(),eventRecord().outgoing().end(),decayIt->first)==
eventRecord().outgoing().end() &&
find(eventRecord().hard().begin(),eventRecord().hard().end(),decayIt->first)==
eventRecord().hard().end()) ++decayIt;
}
assert(decayIt!=eventRecord().decays().end());
PPtr incoming = decayIt->first;
eventRecord().currentDecay(decayIt->second);
// Use this to record if an emission actually happens
bool powhegEmission = !( nEmissions && nEmitted==nEmissions) ? thePowhegDecayEmission : false;
// Decay the particle / sort out its pert proc
Energy showerScale = eventRecord().decay(incoming, powhegEmission);
// Following the decay, the bool powheg emission is updated
// to indicate whether or not an emission occurred
if ( powhegEmission )
nEmitted += 1;
// Check that there is only one particle incoming to the decay
assert(eventRecord().currentDecay()->incoming().size()==1);
// Prepare the event record for the showering of the decay
bool needToShower = eventRecord().prepareDecay(eventRecord().currentDecay(),
offShellPartons());
// Only need to shower if we have coloured outgoing particles
if ( needToShower ) {
// The decays currently considered produce a maximum of 2 chains (with powheg emission)
// so all dipole should have the same scale as returned by the decay function.
assert( eventRecord().chains().size() <= 2 );
for ( auto & ch : eventRecord().chains()) {
for ( auto & dip : ch.dipoles()) {
assert ( showerScale > ZERO );
dip.leftScale( showerScale );
dip.rightScale( showerScale );
}
}
// Prepare vertex record for spin correlations in decay shower
if ( spinCorrelations() )
vertexRecord().prepareParticleDecay(incoming);
// Perform the cascade
doCascade(nEmitted,optHardPt,optCutoff,true);
if ( spinCorrelations() )
vertexRecord().updateParticleDecay();
// Do the constituent mass shell reshuffling
decayConstituentReshuffle(eventRecord().currentDecay());
}
// Update the decays, adding any decays and updating momenta
eventRecord().updateDecays(eventRecord().currentDecay());
eventRecord().decays().erase(decayIt);
}
} catch(...) {
// reset flag
doSubleadingNc = doneSubleadingNc;
throw;
}
doSubleadingNc = doneSubleadingNc;
break;
} catch (RedoShower&) {
resetWeights();
if ( ++nTries > maxtry() )
throw ShowerTriesVeto(maxtry());
eventRecord().clear();
// reset the spininfos
if(sub->incoming().first->spinInfo())
sub->incoming().first->spinInfo()->reset();
if(sub->incoming().second->spinInfo())
sub->incoming().second->spinInfo()->reset();
for(PPtr out : sub->outgoing()) {
if(out->spinInfo()) out->spinInfo()->reset();
}
// prepare for the new shower
eventRecord().prepare(sub, dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr()), newStep(), pdfs(),
ShowerHandler::currentHandler()->generator()->currentEvent()->incoming(),
firstInteraction(), offShellPartons(),
!doSubleadingNc);
if ( doSubleadingNc ) {
theSplittingReweight->updateCurrentHandler();
}
continue;
} catch (...) {
throw;
}
}
tPPair incoming=eventRecord().fillEventRecord(newStep(),firstInteraction(),didRealign);
setDidRunCascade(true);
return incoming;
}
// Reshuffle the outgoing partons from the hard process onto their constituent mass shells
void DipoleShowerHandler::constituentReshuffle() {
if ( constituentReshuffler && ShowerHandler::currentHandler()->retConstituentMasses() ) {
if ( eventRecord().decays().empty() ) {
constituentReshuffler->reshuffle(eventRecord().outgoing(),
eventRecord().incoming(),
eventRecord().intermediates());
return;
}
else {
PList decaying;
for(auto const & dec : eventRecord().decays())
decaying.push_back(dec.first);
constituentReshuffler->hardProcDecayReshuffle( decaying,
eventRecord().outgoing(),
eventRecord().hard(),
eventRecord().incoming(),
eventRecord().intermediates());
}
}
// After reshuffling the hard process, the decays need to be updated
// as this is not done in reshuffle
vector<pair<PPtr,PerturbativeProcessPtr> > decays;
for(auto const & dec : eventRecord().decays() )
decays.push_back({dec.first,dec.second});
for(auto const & dec : decays) {
PPtr unstable = dec.first;
PList::iterator pos = find(eventRecord().intermediates().begin(),
eventRecord().intermediates().end(),
dec.first);
// Update the PPtr in theDecays
if(pos!=eventRecord().intermediates().end()) {
unstable = *pos;
while(!unstable->children().empty()) {
unstable = unstable->children()[0];
}
eventRecord().decays().erase(dec.first);
eventRecord().decays()[unstable] = dec.second;
// Update the momenta of any other particles in the decay chain
// (for externally provided events)
if ( !(eventRecord().decays()[unstable]->outgoing().empty()) )
eventRecord().updateDecayChainMom( unstable , eventRecord().decays()[unstable]);
}
else {
if ( !(eventRecord().decays()[unstable]->outgoing().empty()) ) {
// Update the momenta of any other particles in the decay chain
// (for externally provided events)
// Note this needs to be done for all decaying particles in the
// outgoing/hard regardless of whether that particle radiated
// or was involved in the reshuffling, this is due to the
// transformation performed for IILightKinematics.
if ( (find(eventRecord().outgoing().begin(),
eventRecord().outgoing().end(), unstable) != eventRecord().outgoing().end())
|| (find(eventRecord().hard().begin(),
eventRecord().hard().end(), unstable) != eventRecord().hard().end()) )
eventRecord().updateDecayChainMom( unstable , eventRecord().decays()[unstable]);
}
}
}
eventRecord().currentDecay(PerturbativeProcessPtr());
}
// Reshuffle outgoing partons from a decay process onto their constituent mass shells
void DipoleShowerHandler::decayConstituentReshuffle(PerturbativeProcessPtr decayProc) {
if ( Debug::level > 2 ){
// Test this function by comparing the
// invariant mass of the outgoing decay
// systems before and after reshuffling
Lorentz5Momentum testOutMomBefore (ZERO,ZERO,ZERO,ZERO);
Energy testInvMassBefore = ZERO;
for ( auto const & testDecayOutItBefore : decayProc->outgoing() ) {
testOutMomBefore += testDecayOutItBefore.first->momentum();
}
testInvMassBefore = testOutMomBefore.m();
// decayReshuffle updates both the event record and the decay perturbative process
if ( constituentReshuffler && ShowerHandler::currentHandler()->retConstituentMasses()) {
constituentReshuffler->decayReshuffle(decayProc,
eventRecord().outgoing(),
eventRecord().hard(),
eventRecord().intermediates());
}
Lorentz5Momentum testOutMomAfter (ZERO,ZERO,ZERO,ZERO);
Energy testInvMassAfter = ZERO;
for ( auto const & testDecayOutItAfter : decayProc->outgoing() ) {
testOutMomAfter += testDecayOutItAfter.first->momentum();
}
testInvMassAfter = testOutMomAfter.m();
#ifndef NDEBUG
Energy incomingMass = decayProc->incoming()[0].first->momentum().m();
#endif
assert( abs(testInvMassBefore-incomingMass)/GeV < 1e-5 );
assert( abs(testInvMassBefore-testInvMassAfter)/GeV < 1e-5);
}else{
// decayReshuffle updates both the event record and the decay perturbative process
if ( constituentReshuffler && ShowerHandler::currentHandler()->retConstituentMasses() ) {
constituentReshuffler->decayReshuffle(decayProc,
eventRecord().outgoing(),
eventRecord().hard(),
eventRecord().intermediates());
}
return;
}
}
// Sets the scale of each particle in the dipole chains by finding the smallest
//of several upper bound energy scales: the CMEnergy of the event,
//the transverse mass of outgoing particles, the hardScale (maxPT or maxQ)
//calculated for each dipole (in both configurations) and the veto scale for each particle
void DipoleShowerHandler::hardScales(Energy2 muf) {
// Initalise maximum pt as max CMEnergy of the event
maxPt = generator()->maximumCMEnergy();
if ( restrictPhasespace() ) {
// First interaction == hard collision (i.e. not a MPI collision)
if ( !hardScaleIsMuF() || !firstInteraction() ) {
if ( !eventRecord().outgoing().empty() ) {
for ( auto const & p : eventRecord().outgoing() )
maxPt = min(maxPt,p->momentum().mt());
}
//Look at any non-coloured outgoing particles in the current subprocess
else {
assert(!eventRecord().hard().empty());
Lorentz5Momentum phard(ZERO,ZERO,ZERO,ZERO);
for ( auto const & p : eventRecord().hard())
phard += p->momentum();
Energy mhard = phard.m();
maxPt = mhard;
}
maxPt *= hardScaleFactor();
}
else {
maxPt = hardScaleFactor()*sqrt(muf);
}
muPt = maxPt;
} else {
muPt = hardScaleFactor()*sqrt(muf);
}
if ( doSubleadingNc ) {
return;
}
for ( auto & ch : eventRecord().chains()) {
// Note that minVetoScale is a value for each DipoleChain, not each dipole
// It will contain the minimum veto scale from all of the dipoles in the chain
Energy minVetoScale = -1.*GeV;
for ( auto & dip : ch.dipoles()) {
// max scale per config
Energy maxFirst = ZERO;
Energy maxSecond = ZERO;
// Loop over the kernels for the given dipole.
// For each dipole configuration, calculate ptMax (or QMax if virtuality ordering)
// for each kernel and find the maximum
for ( auto const & k : kernels) {
pair<bool,bool> conf = {true,false};
if ( k->canHandle(dip.index(conf)) ) {
// Look in DipoleChainOrdering for this
Energy scale =
evolutionOrdering()->hardScale(dip.emitter(conf),dip.spectator(conf),
dip.emitterX(conf),dip.spectatorX(conf),
*k,dip.index(conf));
maxFirst = max(maxFirst,scale);
}
conf = {false,true};
if ( k->canHandle(dip.index(conf)) ) {
Energy scale =
evolutionOrdering()->hardScale(dip.emitter(conf),dip.spectator(conf),
dip.emitterX(conf),dip.spectatorX(conf),
*k,dip.index(conf));
maxSecond = max(maxSecond,scale);
}
}
// Find the maximum value from comparing the maxScale found from maxPt and the vetoScale of the particle
if ( dip.leftParticle()->vetoScale() >= ZERO ) {
maxFirst = min(maxFirst,sqrt(dip.leftParticle()->vetoScale()));
// minVetoScale is a value for each DipoleChain, not each dipole
// It contains the minimum veto scale for all the dipoles in the entire DipoleChain
if ( minVetoScale >= ZERO )
minVetoScale = min(minVetoScale,sqrt(dip.leftParticle()->vetoScale()));
else
minVetoScale = sqrt(dip.leftParticle()->vetoScale());
}
if ( dip.rightParticle()->vetoScale() >= ZERO ) {
maxSecond = min(maxSecond,sqrt(dip.rightParticle()->vetoScale()));
if ( minVetoScale >= ZERO )
minVetoScale = min(minVetoScale,sqrt(dip.rightParticle()->vetoScale()));
else
minVetoScale = sqrt(dip.rightParticle()->vetoScale());
}
// Set the emitterScale for both members of each dipole
maxFirst = min(maxPt,maxFirst);
dip.emitterScale({true,false},maxFirst);
maxSecond = min(maxPt,maxSecond);
dip.emitterScale({false,true},maxSecond);
}
// if the smallest veto scale (i.e. from all of the dipoles)
// is smaller than the scale calculated for a particular
// particle in a particular dipole,
// replace the scale with the veto scale
if ( !evolutionOrdering()->independentDipoles() &&
chainOrderVetoScales &&
minVetoScale >= ZERO ) {
for ( auto & dip : ch.dipoles() ) {
dip.leftScale(min(dip.leftScale(),minVetoScale));
dip.rightScale(min(dip.rightScale(),minVetoScale));
}
}
}
}
void DipoleShowerHandler::hardScalesSubleading(list<DipoleSplittingInfo> candidates,
Energy hardPt) {
maxPt = hardPt;//generator()->maximumCMEnergy();
// Note that minVetoScale is a value for each competing dipole (i.e. all dipoles
// for the subleading shower.
// It will contain the minimum veto scale from all of the dipoles
Energy minVetoScale = -1.*GeV;
for ( list<DipoleSplittingInfo>::iterator cand = candidates.begin();
cand != candidates.end(); ++cand ) {
// max scale
Energy maxScale = ZERO;
// Loop over kernels
for ( vector<Ptr<DipoleSplittingKernel>::ptr>::iterator k =
kernels.begin(); k != kernels.end(); ++k ) {
if ( (**k).canHandle(cand->index()) ) {
Energy scale =
evolutionOrdering()->hardScale(cand->emitter(),cand->spectator(),
cand->emitterX(),cand->spectatorX(),
**k,cand->index());
maxScale = max(maxScale,scale);
}
}
if ( cand->emitter()->vetoScale() >= ZERO ) {
maxScale = min(maxScale,sqrt(cand->emitter()->vetoScale()));
if ( minVetoScale >= ZERO )
minVetoScale = min(minVetoScale,sqrt(cand->emitter()->vetoScale()));
else
minVetoScale = sqrt(cand->emitter()->vetoScale());
}
maxScale = min(maxPt,maxScale);
cand->scale(maxScale);
}
if ( !evolutionOrdering()->independentDipoles() &&
chainOrderVetoScales &&
minVetoScale >= ZERO ) {
for ( list<DipoleSplittingInfo>::iterator cand = candidates.begin();
cand != candidates.end(); ++cand ) {
cand->scale(min(cand->scale(),minVetoScale));
}
}
}
void DipoleShowerHandler::addCandidates(PPair particles,
list<DipoleSplittingInfo>& clist) const {
DipoleSplittingInfo candidate;
Energy2 scale = ZERO;
pair<bool,bool> is(particles.first == eventRecord().incoming().first,
particles.second == eventRecord().incoming().second);
if ( (is.first && !is.second) ||
(!is.first && is.second) ) {
scale = -(particles.first->momentum() - particles.second->momentum()).m2();
} else {
scale = (particles.first->momentum() + particles.second->momentum()).m2();
}
DipoleIndex index(particles.first->dataPtr(),particles.second->dataPtr(),
is.first ? eventRecord().pdfs().first : PDF(),
is.second ? eventRecord().pdfs().second : PDF());
candidate.scale(sqrt(scale));
candidate.index(index);
candidate.configuration(make_pair(true,false));
candidate.emitter(particles.first);
candidate.emitterX(is.first ? eventRecord().fractions().first : 1.0);
candidate.spectator(particles.second);
candidate.spectatorX(is.second ? eventRecord().fractions().second : 1.0);
clist.push_back(candidate);
index.swap();
candidate.index(index);
candidate.configuration(make_pair(false,true));
candidate.emitter(particles.second);
candidate.emitterX(is.second ? eventRecord().fractions().second : 1.0);
candidate.spectator(particles.first);
candidate.spectatorX(is.first ? eventRecord().fractions().first : 1.0);
clist.push_back(candidate);
}
void DipoleShowerHandler::getCandidates(list<DipoleSplittingInfo>& clist) const {
clist.clear();
for ( PList::const_iterator i = eventRecord().outgoing().begin();
i != eventRecord().outgoing().end(); ++i ) {
PList::const_iterator j = i; ++j;
for ( ; j != eventRecord().outgoing().end(); ++j ) {
addCandidates(make_pair(*i,*j),clist);
}
// Changed order of *i and inc().first
if ( eventRecord().incoming().first->coloured() )
addCandidates(make_pair(eventRecord().incoming().first,*i),clist);
if ( eventRecord().incoming().second->coloured() )
addCandidates(make_pair(*i,eventRecord().incoming().second),clist);
}
if ( eventRecord().incoming().first->coloured() && eventRecord().incoming().second->coloured() ) {
addCandidates(eventRecord().incoming(),clist);
}
}
void DipoleShowerHandler::performSplitting(DipoleSplittingInfo& split) const {
Ptr<DipoleSplittingKinematics>::tptr kinematics = split.splittingKinematics();
kinematics->generateKinematics(split.emitter()->momentum(),
split.spectator()->momentum(),
split);
split.splitEmitter(split.emitterData()->produceParticle(kinematics->lastEmitterMomentum()));
split.splitSpectator(split.spectatorData()->produceParticle(kinematics->lastSpectatorMomentum()));
split.emission(split.emissionData()->produceParticle(kinematics->lastEmissionMomentum()));
// Setting resolution scales for the particles
split.emission()->scale(sqr(split.lastPt()));
split.splitEmitter()->scale(sqr(split.lastPt()));
split.splitSpectator()->scale(split.spectator()->scale());
PVector neighbours;
if ( DipolePartonSplitter::colourConnected(split.emitter(),
eventRecord().incoming().first) &&
split.emitter() != eventRecord().incoming().first )
neighbours.push_back(eventRecord().incoming().first);
if ( DipolePartonSplitter::colourConnected(split.emitter(),
eventRecord().incoming().second) &&
split.emitter() != eventRecord().incoming().second )
neighbours.push_back(eventRecord().incoming().second);
for ( PList::const_iterator p = eventRecord().outgoing().begin();
p != eventRecord().outgoing().end(); ++p ) {
if ( *p == split.emitter() )
continue;
if ( DipolePartonSplitter::colourConnected(split.emitter(),*p) )
neighbours.push_back(*p);
}
assert(neighbours.size() == 1 || neighbours.size() == 2 );
if ( neighbours.size() == 2 ) {
if ( UseRandom::rnd() < 0.5 )
swap(neighbours[0],neighbours[1]);
}
DipolePartonSplitter::split(split.emitter(),split.splitEmitter(),split.emission(),
neighbours.front(),split.index().initialStateEmitter(),false);
DipolePartonSplitter::change(split.spectator(),split.splitSpectator(),
split.index().initialStateSpectator(),false);
}
Energy DipoleShowerHandler::nextSubleadingSplitting(Energy hardPt,
Energy optHardPt, Energy optCutoff,
const bool decay) {
list<DipoleSplittingInfo> candidates;
getCandidates(candidates);
hardScalesSubleading(candidates,hardPt);
for ( list<DipoleSplittingInfo>::iterator cand = candidates.begin();
cand != candidates.end(); cand++ ) {
cand->scale(hardPt);
}
list<DipoleSplittingInfo>::iterator split = candidates.end();
// Winner of all dipoles
DipoleSplittingInfo winner;
// Winner for the current iteration of the for loop
DipoleSplittingInfo candWinner;
Energy winnerScale = 0.0*GeV;
Energy nextScale = 0.0*GeV;
for ( list<DipoleSplittingInfo>::iterator cand = candidates.begin();
cand != candidates.end(); cand++ ) {
nextScale = getWinner(candWinner,
cand->index(),
cand->emitterX(),cand->spectatorX(),
make_pair(true,false),
cand->emitter(),cand->spectator(),
hardPt,
optHardPt,
optCutoff);
if ( nextScale > winnerScale ) {
winnerScale = nextScale;
winner = candWinner;
split = cand;
winnerIndex = winningKernelIndex;//check
}
}
if ( split == candidates.end() )
return ZERO;
if ( decay )
winner.isDecayProc( true );
split->fill(winner);
performSplitting(*split);
eventRecord().update(*split);
for ( list<DipoleSplittingInfo>::iterator dip = candidates.begin();
dip != candidates.end(); ++dip ) {
if ( dip == split )
continue;
dip->emission(split->emission());
if ( dip->emitter() == split->emitter() ) {
dip->splitEmitter(split->splitEmitter());
} else {
dip->splitEmitter(dip->emitter());
}
if ( dip->spectator() == split->spectator() ) {
dip->splitSpectator(split->splitSpectator());
} else {
dip->splitSpectator(dip->spectator());
}
}
// Update the ShowerHandler of the splitting reweight.
if ( doSubleadingNc ) {
theSplittingReweight->updateCurrentHandler();
}
return split->lastPt();
}
Energy DipoleShowerHandler::getWinner(DipoleSplittingInfo& winner,
const Dipole& dip,
pair<bool,bool> conf,
Energy optHardPt,
Energy optCutoff) {
return
getWinner(winner,dip.index(conf),
dip.emitterX(conf),dip.spectatorX(conf),
conf,dip.emitter(conf),dip.spectator(conf),
dip.emitterScale(conf),optHardPt,optCutoff);
}
Energy DipoleShowerHandler::getWinner(SubleadingSplittingInfo& winner,
Energy optHardPt,
Energy optCutoff) {
return
getWinner(winner,winner.index(),
winner.emitterX(),winner.spectatorX(),
winner.configuration(),
winner.emitter(),winner.spectator(),
winner.startScale(),optHardPt,optCutoff);
}
Energy DipoleShowerHandler::getWinner(DipoleSplittingInfo& winner,
const DipoleIndex& index,
double emitterX, double spectatorX,
pair<bool,bool> conf,
tPPtr emitter, tPPtr spectator,
Energy startScale,
Energy optHardPt,
Energy optCutoff) {
if ( !index.initialStateEmitter() &&
!doFSR() ) {
winner.didStopEvolving();
return 0.0*GeV;
}
if ( index.initialStateEmitter() &&
!doISR() ) {
winner.didStopEvolving();
return 0.0*GeV;
}
if ( index.incomingDecaySpectator()
&& !doFSR() ) {
winner.didStopEvolving();
return 0.0*GeV;
}
// Currently do not split IF dipoles so
// don't evaluate them in order to avoid
// exceptions in the log
if ( index.incomingDecayEmitter() ) {
winner.didStopEvolving();
return 0.0*GeV;
}
DipoleSplittingInfo candidate;
candidate.index(index);
candidate.configuration(conf);
candidate.emitterX(emitterX);
candidate.spectatorX(spectatorX);
candidate.emitter(emitter);
candidate.spectator(spectator);
if ( generators().find(candidate.index()) == generators().end() )
getGenerators(candidate.index(),theSplittingReweight);
//
// NOTE -- needs proper fixing at some point
//
// For some very strange reason, equal_range gives back
// key ranges it hasn't been asked for. This particularly
// happens e.g. for FI dipoles of the same kind, but different
// PDF (hard vs MPI PDF). I can't see a reason for this,
// as DipoleIndex properly implements comparison for equality
// and (lexicographic) ordering; for the time being, we
// use equal_range, extented by an explicit check for wether
// the key is indeed what we wanted. See line after (*) comment
// below.
//
// SW - Update 04/01/2016: Note - This caused a bug for me as I did not
// include equality checks on the decay booleans in the == definition
pair<GeneratorMap::iterator,GeneratorMap::iterator> gens
= generators().equal_range(candidate.index());
Energy winnerScale = 0.0*GeV;
GeneratorMap::iterator winnerGen = generators().end();
for ( GeneratorMap::iterator gen = gens.first; gen != gens.second; ++gen ) {
if ( doPartialUnweighting )
gen->second->doPartialUnweighting(referenceWeight);
// (*) see NOTE above
if ( !(gen->first == candidate.index()) )
continue;
if ( startScale <= gen->second->splittingKinematics()->IRCutoff() )
continue;
Energy dScale =
gen->second->splittingKinematics()->dipoleScale(emitter->momentum(),
spectator->momentum());
// in very exceptional cases happening in DIS
if ( std::isnan( double(dScale/MeV) ) )
throw RedoShower();
candidate.scale(dScale);
// Calculate the mass of the recoil system
// for decay dipoles
if ( candidate.index().incomingDecaySpectator() || candidate.index().incomingDecayEmitter() ) {
Energy recoilMass = gen->second->splittingKinematics()->recoilMassKin(emitter->momentum(),
spectator->momentum());
candidate.recoilMass(recoilMass);
}
// Store emitter and spectator masses, needed in kinematics
if ( candidate.index().emitterData()->mass() != ZERO ) {
if ( !candidate.index().offShellEmitter() )
candidate.emitterMass( emitter->nominalMass() );
else
candidate.emitterMass( emitter->mass() );
}
if ( candidate.index().spectatorData()->mass() != ZERO ) {
if ( !candidate.index().offShellSpectator() )
candidate.spectatorMass( spectator->nominalMass() );
else
candidate.spectatorMass( spectator->mass() );
}
candidate.continuesEvolving();
Energy hardScale = evolutionOrdering()->maxPt(startScale,candidate,*(gen->second->splittingKernel()));
Energy maxPossible =
gen->second->splittingKinematics()->ptMax(candidate.scale(),
candidate.emitterX(), candidate.spectatorX(),
candidate,
*gen->second->splittingKernel());
Energy ircutoff =
optCutoff < gen->second->splittingKinematics()->IRCutoff() ?
gen->second->splittingKinematics()->IRCutoff() :
optCutoff;
if ( maxPossible <= ircutoff ) {
continue;
}
if ( maxPossible >= hardScale ){
candidate.hardPt(hardScale);
}
else {
hardScale = maxPossible;
candidate.hardPt(maxPossible);
}
gen->second->generate(candidate,currentWeights(),optHardPt,optCutoff);
Energy nextScale = evolutionOrdering()->evolutionScale(
gen->second->lastSplitting(),*(gen->second->splittingKernel()));
if ( nextScale > winnerScale ) {
winner.fill(candidate);
gen->second->completeSplitting(winner);
winnerGen = gen;
winnerScale = nextScale;
if ( continueSubleadingNc() )
winningKernelIndex = kernelIndex+1;//check
}
if ( continueSubleadingNc() ) {
kernelIndex++;//check
scales.push_back(nextScale);//check
theWeightsVector.push_back(gen->second->splittingWeightVector());
}
reweight(reweight() * gen->second->splittingWeight());
}
if ( winnerGen == generators().end() ) {
winner.didStopEvolving();
return 0.0*GeV;
}
if ( winner.stoppedEvolving() )
return 0.0*GeV;
return winnerScale;
}
void DipoleShowerHandler::doCascade(unsigned int& emDone,
Energy optHardPt,
Energy optCutoff,
const bool decay) {
if ( nEmissions )
if ( emDone == nEmissions )
return;
if ( doSubleadingNc ) {
unsigned int subEmDone = 0;
// Set the starting scale
Energy hardPt = muPt;
double wref = referenceWeight;
while ( subEmDone < subleadingNcEmissionsLimit && hardPt != ZERO && continueSubleadingNc() ) {
// Clear out the weights from the earlier step
theWeightsVector.clear();
kernelIndex = 0;//check
scales.clear();//check
hardPt = nextSubleadingSplitting( hardPt, optHardPt, optCutoff, decay );
// Partial unweighting
if ( doPartialUnweightingAtEmission ) {
const double w = reweight();
if ( abs(w) < wref ) {
if ( abs(w)/wref < UseRandom::rnd() ) {
// Set weight to zero and end this event
reweight(0.0);
return;
} else
reweight( wref*w/abs(w) );
}
// Update the reference weight after emission
wref *= referenceWeight;
}
// When the winning scale is larger than the cutoff
// remove the added weights that are under the winning scale
if ( hardPt != ZERO ) {
Energy maxq = 0.0*GeV;
#ifndef NDEBUG
size_t iwinner = theWeightsVector.size();//check
#endif
for ( size_t i = 0; i < theWeightsVector.size(); i++ ) {
if ( theWeightsVector[i].size() > 0 ) {
// get<2> is true for an accept step.
if ( std::get<2>(theWeightsVector[i].back())
&& std::get<0>(theWeightsVector[i].back()) > maxq) {
maxq = std::get<0>(theWeightsVector[i].back());
#ifndef NDEBUG
iwinner = i;//check
#endif
}
}
}
assert(winnerIndex-1 == iwinner);//check
double correctionWeight = 1.0;
for ( size_t i = 0; i < theWeightsVector.size(); i++ ) {
for ( size_t j = 0; j < theWeightsVector[i].size(); j++ ) {
if ( std::get<0>(theWeightsVector[i][j]) < maxq )
correctionWeight *= std::get<1>(theWeightsVector[i][j]);
}
}
reweight(reweight()/correctionWeight);
}
// Increment the number of subleading Nc emissions done
subEmDone++;
// Stop if the limit of emissions is reached
if ( nEmissions )
if ( ++emDone == nEmissions )
return;
}
// Subleading shower done, prepare chains for the standard
// dipole shower
eventRecord().prepareChainsSubleading( decay );
// Set scales
for ( list<DipoleChain>::iterator ch = eventRecord().chains().begin();
ch != eventRecord().chains().end(); ch++ ) {
for ( list<Dipole>::iterator dp = ch->dipoles().begin();
dp != ch->dipoles().end(); dp++ ) {
dp->emitterScale(make_pair(true,false),hardPt);
dp->emitterScale(make_pair(false,true),hardPt);
}
}
}
DipoleSplittingInfo winner;
DipoleSplittingInfo dipoleWinner;
while ( eventRecord().haveChain() ) {
if ( verbosity > 2 ) {
generator()->log() << "DipoleShowerHandler selecting splittings for the chain:\n"
<< eventRecord().currentChain() << flush;
}
list<Dipole>::iterator winnerDip = eventRecord().currentChain().dipoles().end();
Energy winnerScale = 0.0*GeV;
Energy nextLeftScale = 0.0*GeV;
Energy nextRightScale = 0.0*GeV;
for ( list<Dipole>::iterator dip = eventRecord().currentChain().dipoles().begin();
dip != eventRecord().currentChain().dipoles().end(); ++dip ) {
nextLeftScale = getWinner(dipoleWinner,*dip,{true,false},optHardPt,optCutoff);
if ( nextLeftScale > winnerScale ) {
winnerScale = nextLeftScale;
winner = dipoleWinner;
winnerDip = dip;
}
nextRightScale = getWinner(dipoleWinner,*dip,{false,true},optHardPt,optCutoff);
if ( nextRightScale > winnerScale ) {
winnerScale = nextRightScale;
winner = dipoleWinner;
winnerDip = dip;
}
if ( evolutionOrdering()->independentDipoles() ) {
Energy dipScale = max(nextLeftScale,nextRightScale);
if ( dip->leftScale() > dipScale )
dip->leftScale(dipScale);
if ( dip->rightScale() > dipScale )
dip->rightScale(dipScale);
}
}
if ( verbosity > 1 ) {
if ( winnerDip != eventRecord().currentChain().dipoles().end() )
generator()->log() << "DipoleShowerHandler selected the splitting:\n"
<< winner << " for the dipole\n"
<< (*winnerDip) << flush;
else
generator()->log() << "DipoleShowerHandler could not select a splitting above the IR cutoff\n"
<< flush;
}
// pop the chain if no dipole did radiate
if ( winnerDip == eventRecord().currentChain().dipoles().end() ) {
eventRecord().popChain();
if ( theEventReweight && eventRecord().chains().empty() )
if ( (theEventReweight->firstInteraction() && firstInteraction()) ||
(theEventReweight->secondaryInteractions() && !firstInteraction()) ) {
double w = theEventReweight->weightCascade(eventRecord().incoming(),
eventRecord().outgoing(),
eventRecord().hard(),theGlobalAlphaS);
reweight(reweight()*w);
}
continue;
}
// Check if the produced splitting would be part
// of a matrix element region in a multi jet merging.
// If so, the optHardPt is set to the current winner scale and the slitting
// is vetoed. Note: It is possible that the current scale is larger than the
// merging scale but another shower configuration shows a scale that is
// below the required scale.
if(firstInteraction() && !decay){
if ( isMERegion( winnerScale , winner , winnerDip) ){
optHardPt=winnerScale; // Vetoed shower.
continue;
}else if( theMergingHelper ){
optHardPt=ZERO;
}
}
// otherwise perform the splitting
didRadiate = true;
eventRecord().isMCatNLOSEvent(false);
eventRecord().isMCatNLOHEvent(false);
pair<list<Dipole>::iterator,list<Dipole>::iterator> children;
DipoleChain* firstChain = nullptr;
DipoleChain* secondChain = nullptr;
// Generate the azimuthal angle
if ( spinCorrelations() )
vertexRecord().generatePhi(winner,*winnerDip);
if ( decay )
winner.isDecayProc( true );
// Note: the dipoles are updated in eventRecord().split(....) after the splitting,
// hence the entire cascade is handled in doCascade
// The dipole scales are updated in dip->split(....)
if ( decay )
winner.isDecayProc( true );
eventRecord().split(winnerDip,winner,children,firstChain,secondChain);
// Update the vertex record following the splitting
if ( spinCorrelations() )
vertexRecord().update(winner);
assert(firstChain && secondChain);
evolutionOrdering()->setEvolutionScale(winnerScale,winner,*firstChain,children);
if ( !secondChain->dipoles().empty() )
evolutionOrdering()->setEvolutionScale(winnerScale,winner,*secondChain,children);
if ( verbosity > 1 ) {
generator()->log() << "DipoleShowerHandler did split the last selected dipole into:\n"
<< (*children.first) << (*children.second) << flush;
}
if ( verbosity > 2 ) {
generator()->log() << "After splitting the last selected dipole, "
<< "DipoleShowerHandler encountered the following chains:\n"
<< (*firstChain) << (*secondChain) << flush;
}
if ( theEventReweight )
if ( (theEventReweight->firstInteraction() && firstInteraction()) ||
(theEventReweight->secondaryInteractions() && !firstInteraction()) ) {
double w = theEventReweight->weight(eventRecord().incoming(),
eventRecord().outgoing(),
eventRecord().hard(),theGlobalAlphaS);
reweight(reweight()*w);
}
if ( nEmissions )
if ( ++emDone == nEmissions )
return;
}
}
bool DipoleShowerHandler::isMERegion(const Energy winnerScale,
const DipoleSplittingInfo & winner,
list<Dipole>::iterator winnerDip ){
// First check if we have a merging setup adn additional conditions.
if(!theMergingHelper)return false;
if(!eventHandler()->currentCollision())return false;
if(theMergingHelper->maxLegs()<=eventRecord().outgoing().size()+
eventRecord().hard().size()
+2)//incoming
return false;
if( theMergingHelper->mergingScale() > winnerScale ) return false;
// Now produce a temporary splitting to check if the final configuration is
// part of the matrix element region
pair<list<Dipole>::iterator,list<Dipole>::iterator> tmpchildren;
DipoleSplittingInfo tmpwinner=winner;
DipoleChain* tmpfirstChain = nullptr;
DipoleChain* tmpsecondChain = nullptr;
auto New=eventRecord().tmpsplit(winnerDip,tmpwinner,
tmpchildren,tmpfirstChain,
tmpsecondChain);
// This is the same function that is used in the ME calculations of the
// multi jet merging.
if (theMergingHelper->matrixElementRegion(New.first,
New.second,
winnerScale,
theMergingHelper->mergingScale())) {
return true;
}else return false;
}
bool DipoleShowerHandler::realign() {
if ( !didRadiate && !intrinsicPtGenerator )
return false;
if ( eventRecord().incoming().first->coloured() ||
eventRecord().incoming().second->coloured() ) {
if ( eventRecord().incoming().first->momentum().perp2()/GeV2 < 1e-10 &&
eventRecord().incoming().second->momentum().perp2()/GeV2 < 1e-10 )
return false;
pair<Lorentz5Momentum,Lorentz5Momentum> inMomenta
(eventRecord().incoming().first->momentum(),
eventRecord().incoming().second->momentum());
LorentzRotation transform((inMomenta.first+inMomenta.second).findBoostToCM());
Axis dir = (transform * inMomenta.first).vect().unit();
Axis rot (-dir.y(),dir.x(),0);
double theta = dir.theta();
if ( lastParticles().first->momentum().z() < ZERO )
theta = -theta;
transform.rotate(-theta,rot);
inMomenta.first = transform*inMomenta.first;
inMomenta.second = transform*inMomenta.second;
assert(inMomenta.first.z() > ZERO &&
inMomenta.second.z() < ZERO);
Energy2 sHat =
(eventRecord().incoming().first->momentum() +
eventRecord().incoming().second->momentum()).m2();
pair<Energy,Energy> masses(eventRecord().incoming().first->mass(),
eventRecord().incoming().second->mass());
pair<Energy,Energy> qs;
if ( !eventRecord().incoming().first->coloured() ) {
assert(masses.second == ZERO);
qs.first = eventRecord().incoming().first->momentum().z();
qs.second = (sHat-sqr(masses.first))/(2.*(qs.first+sqrt(sqr(masses.first)+sqr(qs.first))));
} else if ( !eventRecord().incoming().second->coloured() ) {
assert(masses.first == ZERO);
qs.second = eventRecord().incoming().second->momentum().z();
qs.first = (sHat-sqr(masses.second))/(2.*(qs.second+sqrt(sqr(masses.second)+sqr(qs.second))));
} else {
assert(masses.first == ZERO && masses.second == ZERO);
if ( realignmentScheme == 0 ) {
double yX = eventRecord().pX().rapidity();
double yInt = (transform*eventRecord().pX()).rapidity();
double dy = yX-yInt;
qs.first = (sqrt(sHat)/2.)*exp(dy);
qs.second = (sqrt(sHat)/2.)*exp(-dy);
} else if ( realignmentScheme == 1 ) {
Energy sS = sqrt((lastParticles().first->momentum() +
lastParticles().second->momentum()).m2());
qs.first = eventRecord().fractions().first * sS / 2.;
qs.second = eventRecord().fractions().second * sS / 2.;
}
}
double beta =
(qs.first-qs.second) /
( sqrt(sqr(masses.first)+sqr(qs.first)) +
sqrt(sqr(masses.second)+sqr(qs.second)) );
transform.boostZ(beta);
Lorentz5Momentum tmp;
if ( eventRecord().incoming().first->coloured() ) {
tmp = eventRecord().incoming().first->momentum();
tmp = transform * tmp;
eventRecord().incoming().first->set5Momentum(tmp);
}
if ( eventRecord().incoming().second->coloured() ) {
tmp = eventRecord().incoming().second->momentum();
tmp = transform * tmp;
eventRecord().incoming().second->set5Momentum(tmp);
}
eventRecord().transform(transform);
return true;
}
return false;
}
void DipoleShowerHandler::resetAlphaS(Ptr<AlphaSBase>::tptr as) {
for ( auto & k : kernels) {
if ( !k->alphaS() )
k->alphaS(as);
k->renormalizationScaleFreeze(theRenormalizationScaleFreeze);
k->factorizationScaleFreeze(theFactorizationScaleFreeze);
}
// clear the generators to be rebuild
// actually, there shouldn't be any generators
// when this happens.
generators().clear();
}
void DipoleShowerHandler::resetReweight(Ptr<DipoleSplittingReweight>::tptr rw) {
for ( auto & g : generators() )
g.second->splittingReweight(rw);
}
void DipoleShowerHandler::getGenerators(const DipoleIndex& ind,
Ptr<DipoleSplittingReweight>::tptr rw) {
bool gotone = false;
for ( auto & k : kernels ) {
if ( k->canHandle(ind) ) {
if ( verbosity > 0 ) {
generator()->log() << "DipoleShowerHandler encountered the dipole configuration\n"
<< ind << " in event number "
<< eventHandler()->currentEvent()->number()
<< "\nwhich can be handled by the splitting kernel '"
<< k->name() << "'.\n" << flush;
}
gotone = true;
Ptr<DipoleSplittingGenerator>::ptr nGenerator =
new_ptr(DipoleSplittingGenerator());
nGenerator->doCompensate(theDoCompensate);
nGenerator->splittingKernel(k);
if ( renormalizationScaleFactor() != 1. )
nGenerator->splittingKernel()->renormalizationScaleFactor(renormalizationScaleFactor());
if ( factorizationScaleFactor() != 1. )
nGenerator->splittingKernel()->factorizationScaleFactor(factorizationScaleFactor());
if ( !nGenerator->splittingReweight() )
nGenerator->splittingReweight(rw);
nGenerator->splittingKernel()->freezeGrid(theFreezeGrid);
nGenerator->splittingKernel()->detuning(theDetuning);
GeneratorMap::const_iterator equivalent = generators().end();
for ( GeneratorMap::const_iterator eq = generators().begin();
eq != generators().end(); ++eq ) {
if ( !eq->second->wrapping() )
if ( k->canHandleEquivalent(ind,*(eq->second->splittingKernel()),eq->first) ) {
equivalent = eq;
if ( verbosity > 0 ) {
generator()->log() << "The dipole configuration "
<< ind
<< " can equivalently be handled by the existing\n"
<< "generator for configuration "
<< eq->first << " using the kernel '"
<< eq->second->splittingKernel()->name()
<< "'\n" << flush;
}
break;
}
}
if ( equivalent != generators().end() ) {
nGenerator->wrap(equivalent->second);
}
DipoleSplittingInfo dummy;
dummy.index(ind);
nGenerator->prepare(dummy);
generators().insert({ind,nGenerator});
}
}
if ( !gotone ) {
throw Exception()
<< "DipoleShowerHandler could not "
<< "find a splitting kernel which is able "
<< "to handle splittings off the dipole "
<< ind << ".\n"
<< "Please check the input files."
<< Exception::runerror;
}
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleShowerHandler::doinit() {
ShowerHandler::doinit();
if ( theGlobalAlphaS )
resetAlphaS(theGlobalAlphaS);
// copy off-shell particle ids before showering from input vector to the
// set used in the simulation
if ( theColouredOffShellInShower.empty() ) {
for(unsigned int ix=0;ix<theInputColouredOffShellInShower.size();++ix)
theColouredOffShellInShower.insert(abs(theInputColouredOffShellInShower[ix]));
}
// work out which shower phase space to use for the matching
bool zChoice0 = false;
bool zChoice1 = false;
size_t zChoiceOther = false;
for ( auto & k : kernels) {
if ( k->splittingKinematics()->openZBoundaries() == 0 )
zChoice0 = true;
else if ( k->splittingKinematics()->openZBoundaries() == 1 )
zChoice1 = true;
else
zChoiceOther = true;
// either inconsistent or other option which cannot be handled by the matching
if ( zChoice0 && zChoice1 ) {
zChoiceOther = true; break;
}
}
if ( zChoiceOther )
theZBoundaries = 2;
else if ( zChoice1 )
theZBoundaries = 1;
else if ( zChoice0 )
theZBoundaries = 0;
}
void DipoleShowerHandler::dofinish() {
ShowerHandler::dofinish();
}
void DipoleShowerHandler::doinitrun() {
ShowerHandler::doinitrun();
}
void DipoleShowerHandler::persistentOutput(PersistentOStream & os) const {
os << kernels << theEvolutionOrdering
<< constituentReshuffler << intrinsicPtGenerator
<< theGlobalAlphaS << chainOrderVetoScales
<< nEmissions << discardNoEmissions << firstMCatNLOEmission
<< thePowhegDecayEmission
//<< theAnalyseSpinCorrelations
<< doSubleadingNc << subleadingNcEmissionsLimit
<< densityOperatorEvolution << ounit(densityOperatorCutoff,GeV2)
<< doPartialUnweightingAtEmission
<< doPartialUnweighting << referenceWeight
<< cmecReweightFactor << negCMECScaling
<< realignmentScheme << verbosity << printEvent
<< ounit(theRenormalizationScaleFreeze,GeV)
<< ounit(theFactorizationScaleFreeze,GeV)
<< theShowerApproximation
<< theDoCompensate << theFreezeGrid << theDetuning
<< theEventReweight << theSplittingReweight << ounit(maxPt,GeV)
<< ounit(muPt,GeV)<< theMergingHelper << theColouredOffShellInShower
<< theInputColouredOffShellInShower
<< theZBoundaries;
}
void DipoleShowerHandler::persistentInput(PersistentIStream & is, int) {
is >> kernels >> theEvolutionOrdering
>> constituentReshuffler >> intrinsicPtGenerator
>> theGlobalAlphaS >> chainOrderVetoScales
>> nEmissions >> discardNoEmissions >> firstMCatNLOEmission
>> thePowhegDecayEmission
//>> theAnalyseSpinCorrelations
>> doSubleadingNc >> subleadingNcEmissionsLimit
>> densityOperatorEvolution >> iunit(densityOperatorCutoff,GeV2)
>> doPartialUnweightingAtEmission
>> doPartialUnweighting >> referenceWeight
>> cmecReweightFactor >> negCMECScaling
>> realignmentScheme >> verbosity >> printEvent
>> iunit(theRenormalizationScaleFreeze,GeV)
>> iunit(theFactorizationScaleFreeze,GeV)
>> theShowerApproximation
>> theDoCompensate >> theFreezeGrid >> theDetuning
>> theEventReweight >> theSplittingReweight >> iunit(maxPt,GeV)
>> iunit(muPt,GeV)>>theMergingHelper >> theColouredOffShellInShower
>> theInputColouredOffShellInShower
>> theZBoundaries;
}
ClassDescription<DipoleShowerHandler> DipoleShowerHandler::initDipoleShowerHandler;
// Definition of the static class description member.
void DipoleShowerHandler::Init() {
static ClassDocumentation<DipoleShowerHandler> documentation
("The DipoleShowerHandler class manages the showering using "
"the dipole shower algorithm.",
"The shower evolution was performed using the algorithm described in "
"\\cite{Platzer:2009jq} and \\cite{Platzer:2011bc}.",
"%\\cite{Platzer:2009jq}\n"
"\\bibitem{Platzer:2009jq}\n"
"S.~Platzer and S.~Gieseke,\n"
"``Coherent Parton Showers with Local Recoils,''\n"
" JHEP {\\bf 1101}, 024 (2011)\n"
"arXiv:0909.5593 [hep-ph].\n"
"%%CITATION = ARXIV:0909.5593;%%\n"
"%\\cite{Platzer:2011bc}\n"
"\\bibitem{Platzer:2011bc}\n"
"S.~Platzer and S.~Gieseke,\n"
"``Dipole Showers and Automated NLO Matching in Herwig,''\n"
"arXiv:1109.6256 [hep-ph].\n"
"%%CITATION = ARXIV:1109.6256;%%");
static RefVector<DipoleShowerHandler,DipoleSplittingKernel> interfaceKernels
("Kernels",
"Set the splitting kernels to be used by the dipole shower.",
&DipoleShowerHandler::kernels, -1, false, false, true, false, false);
static Reference<DipoleShowerHandler,DipoleEvolutionOrdering> interfaceEvolutionOrdering
("EvolutionOrdering",
"Set the evolution ordering to be used.",
&DipoleShowerHandler::theEvolutionOrdering, false, false, true, false, false);
static Reference<DipoleShowerHandler,ConstituentReshuffler> interfaceConstituentReshuffler
("ConstituentReshuffler",
"The object to be used to reshuffle partons to their constitutent mass shells.",
&DipoleShowerHandler::constituentReshuffler, false, false, true, true, false);
static Reference<DipoleShowerHandler,IntrinsicPtGenerator> interfaceIntrinsicPtGenerator
("IntrinsicPtGenerator",
"Set the object in charge to generate intrinsic pt for incoming partons.",
&DipoleShowerHandler::intrinsicPtGenerator, false, false, true, true, false);
static Reference<DipoleShowerHandler,AlphaSBase> interfaceGlobalAlphaS
("GlobalAlphaS",
"Set a global strong coupling for all splitting kernels.",
&DipoleShowerHandler::theGlobalAlphaS, false, false, true, true, false);
// Start: Trying to add interface for the subleading Nc
static Switch<DipoleShowerHandler,bool> interfaceDoSubleadingNc
("DoSubleadingNc",
"Switch on or off subleading Nc corrections.",
&DipoleShowerHandler::doSubleadingNc, true, false, false);
static SwitchOption interfaceDoSubleadingNcOn
(interfaceDoSubleadingNc,
"On",
"Switch on subleading Nc corrections.",
true);
static SwitchOption interfaceDoSubleadingNcOff
(interfaceDoSubleadingNc,
"Off",
"Switch off subleading Nc corrections.",
false);
// Limit for how many subleading Nc emissions should be calculated
static Parameter<DipoleShowerHandler,size_t> interfaceSubleadingNcEmissionsLimit
("SubleadingNcEmissionsLimit",
"Number of emissions to calculate subleading Nc corrections for.",
&DipoleShowerHandler::subleadingNcEmissionsLimit,0,0,0,
false, false, Interface::lowerlim);
static Parameter<DipoleShowerHandler,int> interfaceDensityOperatorEvolution
("DensityOperatorEvolution",
"Scheme for evolving the density operator.",
&DipoleShowerHandler::densityOperatorEvolution,0,0,0,
false, false, Interface::lowerlim);
static Parameter<DipoleShowerHandler,Energy2> interfaceDensityOperatorCutoff
("DensityOperatorCutoff",
"Cutoff for momentum invariants for the density operator evolution.",
&DipoleShowerHandler::densityOperatorCutoff,GeV2,1.0*GeV2,0.0*GeV2,0*GeV2,
false, false, Interface::lowerlim);
static Switch<DipoleShowerHandler,bool> interfaceDoPartialUnweightingAtEmission
("DoPartialUnweightingAtEmission",
"Switch on or off partial unweighting at the emission level.",
&DipoleShowerHandler::doPartialUnweightingAtEmission,true,false,false);
static SwitchOption interfaceDoPartialUnweightingAtEmissionOn
(interfaceDoPartialUnweightingAtEmission,
"On",
"Switch on partial unweighting.",
true);
static SwitchOption interfaceDoPartialUnweightingAtEmissionOff
(interfaceDoPartialUnweightingAtEmission,
"Off",
"Switch off partial unweighting.",
false);
static Switch<DipoleShowerHandler,bool> interfaceDoPartialUnweighting
("DoPartialUnweighting",
"Switch on or off partial unweighting at the dipole splitting level.",
&DipoleShowerHandler::doPartialUnweighting,true,false,false);
static SwitchOption interfaceDoPartialUnweightingOn
(interfaceDoPartialUnweighting,
"On",
"Switch on partial unweighting.",
true);
static SwitchOption interfaceDoPartialUnweightingOff
(interfaceDoPartialUnweighting,
"Off",
"Switch off partial unweighting.",
false);
static Parameter<DipoleShowerHandler,double> interfaceReferenceWeight
("ReferenceWeight",
"Reference weight for the partial unweighting.",
&DipoleShowerHandler::referenceWeight,0.1,0.0,0,
false, false, Interface::lowerlim);
static Parameter<DipoleShowerHandler,double> interfaceCMECReweightFactor
("CMECReweightFactor",
"Factor used in the reweighting algorithm.",
&DipoleShowerHandler::cmecReweightFactor,1.0,0.0,0,
false, false, Interface::lowerlim);
static Parameter<DipoleShowerHandler,double> interfaceNegCMECScaling
("NegCMECScaling",
"Scaling factor for the negative colour matrix element corrections (CMECs).",
&DipoleShowerHandler::negCMECScaling,0.0,0.0,0,
false, false, Interface::lowerlim);
static Switch<DipoleShowerHandler,int> interfaceRealignmentScheme
("RealignmentScheme",
"The realignment scheme to use.",
&DipoleShowerHandler::realignmentScheme, 0, false, false);
static SwitchOption interfaceRealignmentSchemePreserveRapidity
(interfaceRealignmentScheme,
"PreserveRapidity",
"Preserve the rapidity of non-coloured outgoing system.",
0);
static SwitchOption interfaceRealignmentSchemeEvolutionFractions
(interfaceRealignmentScheme,
"EvolutionFractions",
"Use momentum fractions as generated by the evolution.",
1);
static SwitchOption interfaceRealignmentSchemeCollisionFrame
(interfaceRealignmentScheme,
"CollisionFrame",
"Determine realignment from collision frame.",
2);
static Switch<DipoleShowerHandler,bool> interfaceChainOrderVetoScales
("ChainOrderVetoScales",
"[experimental] Switch the chain ordering for veto scales on or off.",
&DipoleShowerHandler::chainOrderVetoScales, true, false, false);
static SwitchOption interfaceChainOrderVetoScalesYes
(interfaceChainOrderVetoScales,
"Yes",
"Switch on chain ordering for veto scales.",
true);
static SwitchOption interfaceChainOrderVetoScalesNo
(interfaceChainOrderVetoScales,
"No",
"Switch off chain ordering for veto scales.",
false);
interfaceChainOrderVetoScales.rank(-1);
static Parameter<DipoleShowerHandler,unsigned int> interfaceNEmissions
("NEmissions",
"[debug option] Limit the number of emissions to be generated. Zero does not limit the number of emissions.",
&DipoleShowerHandler::nEmissions, 0, 0, 0,
false, false, Interface::lowerlim);
interfaceNEmissions.rank(-1);
static Switch<DipoleShowerHandler,bool> interfaceDiscardNoEmissions
("DiscardNoEmissions",
"[debug option] Discard events without radiation.",
&DipoleShowerHandler::discardNoEmissions, false, false, false);
static SwitchOption interfaceDiscardNoEmissionsYes
(interfaceDiscardNoEmissions,
"Yes",
"Discard events without radiation.",
true);
static SwitchOption interfaceDiscardNoEmissionsNo
(interfaceDiscardNoEmissions,
"No",
"Do not discard events without radiation.",
false);
interfaceDiscardNoEmissions.rank(-1);
static Switch<DipoleShowerHandler,bool> interfaceFirstMCatNLOEmission
("FirstMCatNLOEmission",
"[debug option] Only perform the first MC@NLO emission.",
&DipoleShowerHandler::firstMCatNLOEmission, false, false, false);
static SwitchOption interfaceFirstMCatNLOEmissionYes
(interfaceFirstMCatNLOEmission,
"Yes",
"Perform only the first MC@NLO emission.",
true);
static SwitchOption interfaceFirstMCatNLOEmissionNo
(interfaceFirstMCatNLOEmission,
"No",
"Produce all emissions.",
false);
interfaceFirstMCatNLOEmission.rank(-1);
static Parameter<DipoleShowerHandler,int> interfaceVerbosity
("Verbosity",
"[debug option] Set the level of debug information provided.",
&DipoleShowerHandler::verbosity, 0, 0, 0,
false, false, Interface::lowerlim);
interfaceVerbosity.rank(-1);
static Parameter<DipoleShowerHandler,int> interfacePrintEvent
("PrintEvent",
"[debug option] The number of events for which debugging information should be provided.",
&DipoleShowerHandler::printEvent, 0, 0, 0,
false, false, Interface::lowerlim);
interfacePrintEvent.rank(-1);
static Parameter<DipoleShowerHandler,Energy> interfaceRenormalizationScaleFreeze
("RenormalizationScaleFreeze",
"The freezing scale for the renormalization scale.",
&DipoleShowerHandler::theRenormalizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<DipoleShowerHandler,Energy> interfaceFactorizationScaleFreeze
("FactorizationScaleFreeze",
"The freezing scale for the factorization scale.",
&DipoleShowerHandler::theFactorizationScaleFreeze, GeV, 2.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Switch<DipoleShowerHandler,bool> interfaceDoCompensate
("DoCompensate",
"",
&DipoleShowerHandler::theDoCompensate, false, false, false);
static SwitchOption interfaceDoCompensateYes
(interfaceDoCompensate,
"Yes",
"",
true);
static SwitchOption interfaceDoCompensateNo
(interfaceDoCompensate,
"No",
"",
false);
static Parameter<DipoleShowerHandler,unsigned long> interfaceFreezeGrid
("FreezeGrid",
"",
&DipoleShowerHandler::theFreezeGrid, 500000, 1, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleShowerHandler,double> interfaceDetuning
("Detuning",
"A value to detune the overestimate kernel.",
&DipoleShowerHandler::theDetuning, 1.0, 1.0, 0,
false, false, Interface::lowerlim);
static Reference<DipoleShowerHandler,DipoleEventReweight> interfaceEventReweight
("EventReweight",
"",
&DipoleShowerHandler::theEventReweight, false, false, true, true, false);
static Reference<DipoleShowerHandler,DipoleSplittingReweight> interfaceSplittingReweight
("SplittingReweight",
"Set the splitting reweight.",
&DipoleShowerHandler::theSplittingReweight, false, false, true, true, false);
static Switch<DipoleShowerHandler, bool> interfacePowhegDecayEmission
("PowhegDecayEmission",
"Use Powheg style emission for the decays",
&DipoleShowerHandler::thePowhegDecayEmission, true, false, false);
static SwitchOption interfacePowhegDecayEmissionYes
(interfacePowhegDecayEmission,"Yes","Powheg decay emission on", true);
static SwitchOption interfacePowhegDecayEmissionNo
(interfacePowhegDecayEmission,"No","Powheg decay emission off", false);
static ParVector<DipoleShowerHandler,long> interfaceOffShellInShower
("OffShellInShower",
"PDG codes of the coloured particles that can be off-shell in the process.",
&DipoleShowerHandler::theInputColouredOffShellInShower, -1, 0l, -10000000l, 10000000l,
false, false, Interface::limited);
/*
static Switch<DipoleShowerHandler, bool> interfaceAnalyseSpinCorrelations
("AnalyseSpinCorrelations",
"Record the information required for the spin correlation analyis.",
&DipoleShowerHandler::theAnalyseSpinCorrelations, false, false, false);
static SwitchOption interfaceAnalyseSpinCorrelationsYes
(interfaceAnalyseSpinCorrelations,"Yes","Record the information for analysing the spin correlations.", true);
static SwitchOption interfaceAnalyseSpinCorrelationsNo
(interfaceAnalyseSpinCorrelations,"No","Do not record extra information.", false);
*/
}
diff --git a/Shower/Dipole/DipoleShowerHandler.h b/Shower/Dipole/DipoleShowerHandler.h
--- a/Shower/Dipole/DipoleShowerHandler.h
+++ b/Shower/Dipole/DipoleShowerHandler.h
@@ -1,764 +1,756 @@
// -*- C++ -*-
//
// DipoleShowerHandler.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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.h"
#include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
#include "Herwig/Shower/Dipole/SpinCorrelations/DipoleVertexRecord.h"
#include "Herwig/MatrixElement/Matchbox/Utility/DensityOperator.h"
#include <tuple>
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Stephen Webster
*
* \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:
inline void colourPrint();
/**
* 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);
virtual void cascade(tPVector);
/**
* 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));}
/**
* Return the number of scale dependent active flavours from
* the alpha_s object.
*/
double Nf(Energy Q)const{return theGlobalAlphaS->Nf(sqr(Q));}
/*
* Access the vertex record
*/
DipoleVertexRecord& vertexRecord() { return theVertexRecord; }
/**
* Return the event record
*/
const DipoleVertexRecord& vertexRecord() const { return theVertexRecord; }
/**
* Set the pointer to the Merging Helper.
* Used by the merging factory.
*/
void setMerger(Ptr<MergerBase>::ptr mh){theMergingHelper=mh;}
public:
/**
* Return the dictionary for the incoming particles and outgoing partons
* in the event, will be empty if subleading Nc is turned off.
*/
const map<PPtr,size_t>& particleIndices() const { return eventRecord().particleIndices(); }
/**
* Return the particle data vector of the particles in the event, will
* be empty if subleading Nc is turned off.
*/
const cPDVector& particlesAfter() const { return eventRecord().particlesAfter(); }
/**
* Return the density operator from the event record.
*/
DensityOperator& densityOperator() { return eventRecord().densityOperator(); }
/**
* Return the colour matrix element correction map, will be empty if
* subleading Nc is turned off. NOT USED, REMOVE
*/
const map<pair<vector<PDT::Colour>,pair<size_t,size_t> >,double>& correlatorMap() const {
return eventRecord().densityOperator().correlatorMap();
}
/**
* Return the colour basis used in the density operator. NOT USED, REMOVE
*/
Ptr<ColourBasis>::tptr colourBasis() {
return eventRecord().densityOperator().colourBasis();
}
/**
* Return the continue subleading Nc flag from the event record.
*/
bool continueSubleadingNc() const { return eventRecord().getContinueSubleadingNc(); }
protected:
/**
* Add the possible splitting candidates given a pair of emitting particles
*/
void addCandidates(PPair particles, list<DipoleSplittingInfo>& clist) const;
/**
* Get all possible radiating dipoles
*/
void getCandidates(list<DipoleSplittingInfo>& clist) const;
/**
* Perform a splitting independent of any chains
*/
void performSplitting(DipoleSplittingInfo&) const;
/**
* Generate the next subleading Nc improved splitting and return the scale
*/
Energy nextSubleadingSplitting(Energy hardPt,
Energy optHardPt, Energy optCutoff,
const bool decay);
protected:
typedef multimap<DipoleIndex,Ptr<DipoleSplittingGenerator>::ptr> GeneratorMap;
/**
* The main method which manages the showering of a subprocess.
*/
virtual tPPair cascade(tSubProPtr sub, XCombPtr xcomb) {
return cascade(sub,xcomb,ZERO,ZERO);
}
/**
* The main method which manages the showering of a subprocess.
*/
tPPair cascade(tSubProPtr sub, XCombPtr xcomb,
Energy optHardPt, Energy optCutoff);
/**
* 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);
/**
* Setup the hard scales of the dipoles after subleading emissions.//debug
*/
void hardScalesSubleading(list<DipoleSplittingInfo> candidates,Energy hardPt);
/**
* Return the evolution ordering
*/
Ptr<DipoleEvolutionOrdering>::tptr evolutionOrdering() const { return theEvolutionOrdering; }
/**
* Reshuffle to constituent mass shells
*/
void constituentReshuffle();
/**
* Reshuffle to constituent mass shells
*/
void decayConstituentReshuffle( PerturbativeProcessPtr decayProc);
/**
* 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;
}
/**
* Return the set of offshell parton ids.
**/
const set<long>& offShellPartons() { return theColouredOffShellInShower; }
/**
* In a merging setup this function checks if the next shower
* configuration is part of the matrix element region.
*/
bool isMERegion(const Energy winnerScale,
const DipoleSplittingInfo & winner,
const list<Dipole>::iterator winnerDip);
/**
* Realign the event such as to have the incoming partons along thre
* beam axes.
*/
bool realign();
/**
* The choice of z boundaries; 0 = restricted, 1 = open, 2 = mixed/other
*/
virtual int showerPhaseSpaceOption() const {
return theZBoundaries;
}
protected:
/**
* Perform the cascade.
*/
void doCascade(unsigned int& emDone,
Energy optHardPt = ZERO,
Energy optCutoff = ZERO,
const bool decay = false);
/**
* 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(DipoleSplittingInfo& winner,
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;
/**
* True if powheg style emissions are to be used in the decays
*/
bool thePowhegDecayEmission;
/**
* Switch to record information required for the
* nearest neighbour analysis.
*/
//bool theAnalyseSpinCorrelations;
/**
* The realignment scheme
*/
int realignmentScheme;
/**
* Switch on or off subleading Nc corrections
*/
bool doSubleadingNc;
/**
* Number of emissions to do subleading Nc corrections to.
*/
size_t subleadingNcEmissionsLimit;
/**
* Current reference weight used for partial unweighting of the
* subleading colour shower (updated each emission).
*/
int currentReferenceWeight;
/**
* Integer used to set which method of evolving the density operator
* to use:
* 0 - Vijk is Eikonal but there is a cutoff.
* 1 - Vijk is Eikonal.
* 2 - Vijk=1 for all i,j,k.
* 3 - Semi-leading Nc, Vijk=0 for all
*/
int densityOperatorEvolution;
/**
* Cutoff scale for the invariants (e.g. pEmitter*pEmission) in the
* Eikonal dipole kernel, Vijk.
*/
Energy2 densityOperatorCutoff;
/**
* Switch on or off partial unweighting in after each subleading emission.
*/
bool doPartialUnweightingAtEmission;
/**
* Switch on or off partial unweighting in the splitting generator.
*/
bool doPartialUnweighting;
/**
* Reference weight for the partial unweighting.
*/
double referenceWeight;
/**
* Factor changing the acceptance probability for the veto algorithm.
*/
double cmecReweightFactor;
/**
* Scaling factor for the negative colour matrix element corrections.
*/
double negCMECScaling;
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 vertex record.
**/
DipoleVertexRecord theVertexRecord;
/**
* 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;
/**
* Vector of candidate splittings containing a vector of the
* weights, scale and a bool for every step in the reweighted
* veto algorithm. The bool is true for an accept step.
*/
vector<vector<std::tuple<Energy,double,bool> > > theWeightsVector;
/**
* Winning candidate index.
*/
size_t winnerIndex;//debug
size_t kernelIndex;//debug
size_t winningKernelIndex;//debug
vector<Energy> scales;//debug
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;
/**
* The merging helper takes care of merging multiple LO and NLO
* cross sections. Here we need to check if an emission would
* radiate in the matrix element region of an other multipicity.
* If so, the emission is vetoed.
*/
Ptr<MergerBase>::ptr theMergingHelper;
/**
* PDG codes of the partons which can have an off-shell mass,
* this is fast storage for use during running
*/
set<long> theColouredOffShellInShower;
/**
* PDG codes of the partons which can have an off-shell mass,
* this is a vector that is interfaced so they can be changed
*/
vector<long> theInputColouredOffShellInShower;
/**
* The choice of z boundaries; 0 = restricted, 1 = open, 2 = mixed/other
*/
int theZBoundaries;
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 &) = delete;
};
}
#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/Kernels/ColourMatrixElementCorrection.cc b/Shower/Dipole/Kernels/ColourMatrixElementCorrection.cc
--- a/Shower/Dipole/Kernels/ColourMatrixElementCorrection.cc
+++ b/Shower/Dipole/Kernels/ColourMatrixElementCorrection.cc
@@ -1,91 +1,89 @@
// -*- C++ -*-
//
// ColourMatrixElementCorrection.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 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 ColourMatrixElementCorrection class.
//
#include "ColourMatrixElementCorrection.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/Shower/Dipole/DipoleShowerHandler.h"
using namespace Herwig;
ColourMatrixElementCorrection::ColourMatrixElementCorrection():lambda(1.0),negCMECScaling(1.0) {}
-ColourMatrixElementCorrection::~ColourMatrixElementCorrection() {}
-
IBPtr ColourMatrixElementCorrection::clone() const {
return new_ptr(*this);
}
IBPtr ColourMatrixElementCorrection::fullclone() const {
return new_ptr(*this);
}
double ColourMatrixElementCorrection::cmec(const DipoleSplittingInfo& dsplit) const {
// Do not calculate CMECs if the subleading Nc shower has stopped
if ( !(currentHandler()->continueSubleadingNc()) ) {
return 1.;
}
const PPtr em = dsplit.emitter();
const PPtr sp = dsplit.spectator();
const tcPDPtr emis = dsplit.emissionData();
// Get the dictionary from particle pointers to herwig particle numbers
const map<PPtr,size_t>& theDictionary = currentHandler()->particleIndices();
const cPDVector& theParticles = currentHandler()->particlesAfter();
// Use the dictionary to find
// - emitter index
// - spectator index
// - emission ParticleID
const std::tuple<size_t,size_t,long> ikemission = std::make_tuple(theDictionary.at(em),
theDictionary.at(sp),
emis->id());
double factor = currentHandler()->densityOperator().colourMatrixElementCorrection(ikemission,theParticles);
return factor > 0.0 ? factor : negCMECScaling*factor;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void ColourMatrixElementCorrection::persistentOutput(PersistentOStream &) const {
// *** ATTENTION *** os << ; // Add all member variable which should be written persistently here.
}
void ColourMatrixElementCorrection::persistentInput(PersistentIStream &, int) {
// *** ATTENTION *** is >> ; // Add all member variable which should be read persistently here.
}
// *** 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<ColourMatrixElementCorrection,Herwig::DipoleSplittingReweight>
describeHerwigColourMatrixElementCorrection("Herwig::ColourMatrixElementCorrection",
"HwDipoleShower.so");
void ColourMatrixElementCorrection::Init() {
static ClassDocumentation<ColourMatrixElementCorrection> documentation
("There is no documentation for the ColourMatrixElementCorrection class");
}
diff --git a/Shower/Dipole/Kernels/ColourMatrixElementCorrection.h b/Shower/Dipole/Kernels/ColourMatrixElementCorrection.h
--- a/Shower/Dipole/Kernels/ColourMatrixElementCorrection.h
+++ b/Shower/Dipole/Kernels/ColourMatrixElementCorrection.h
@@ -1,171 +1,163 @@
// -*- C++ -*-
//
// ColourMatrixElementCorrection.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 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_ColourMatrixElementCorrection_H
#define Herwig_ColourMatrixElementCorrection_H
//
// This is the declaration of the ColourMatrixElementCorrection class.
//
#include "Herwig/Shower/Dipole/Base/DipoleSplittingReweight.h"
#include <tuple>
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Johan Thoren, Simon Platzer
*
* \brief ColourMatrixElementCorrection is implementing colour matrix element
* corrections through the weighted Sudakov algorithm
*
* @see \ref ColourMatrixElementCorrectionInterfaces "The interfaces"
* defined for ColourMatrixElementCorrection.
*/
class ColourMatrixElementCorrection: public DipoleSplittingReweight {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
ColourMatrixElementCorrection();
- /**
- * The destructor.
- */
- virtual ~ColourMatrixElementCorrection();
- //@}
-
public:
/**
* Calculate and cache the colour matrix element correction factor
* for the given splitting type.
*/
double cmec(const DipoleSplittingInfo&) const;
/**
* Return the reweighting factor for the given splitting type.
*/
virtual double evaluate(const DipoleSplittingInfo& s) const {
return cmec(s);
}
/**
* Return the absolute value of the colour matrix element correction
* as an enhancement hint for the sampling of the un-reweighted
* splitting kernel.
*/
virtual double hint(const DipoleSplittingInfo& s) const {
if ( hintOnly(s) )
return cmec(s);
return abs(cmec(s))*lambda;
}
/**
* Return true, if the reweight can be entirely absorbed into the hint. A
* possible detuning will be switched off.
*/
virtual bool hintOnly(const DipoleSplittingInfo& s) const {
return cmec(s) > 0.;
}
/**
* Set the factor in front of enhance used by the veto algorithm.
*/
virtual void reweightFactor(const double c) {
assert(c > 0.0);
lambda = c;
}
/**
* Set the factor in front of enhance used by the veto algorithm.
*/
virtual void negativeScaling(const double c) {
assert(c >= 0.0);
negCMECScaling = c;
}
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:
/**
* Factor to shuffle the magnitude of the CMEC between the splitting kernel
* and the weight in the reweighted veto algorithm.
*/
double lambda;
/**
* Scaling factor multiplying all of the negative colour matrix element
* corrections. The physically sensible value is 1.0, but this factor can
* be used to examine the effects of the negative contributions.
*/
double negCMECScaling;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
ColourMatrixElementCorrection & operator=(const ColourMatrixElementCorrection &) = delete;
};
}
#endif /* Herwig_ColourMatrixElementCorrection_H */
diff --git a/Shower/Dipole/Kernels/DipoleSplittingKernel.cc b/Shower/Dipole/Kernels/DipoleSplittingKernel.cc
--- a/Shower/Dipole/Kernels/DipoleSplittingKernel.cc
+++ b/Shower/Dipole/Kernels/DipoleSplittingKernel.cc
@@ -1,411 +1,408 @@
// -*- C++ -*-
//
// DipoleSplittingKernel.cc is a part of Herwig -
// A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 DipoleSplittingKernel class.
//
#include "DipoleSplittingKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/Shower/ShowerHandler.h"
using namespace Herwig;
DipoleSplittingKernel::DipoleSplittingKernel()
: HandlerBase(), theScreeningScale(0.0*GeV),
thePresamplingPoints(2000), theMaxtry(100000),
theFreezeGrid(500000),
theDetuning(1.0),
theStrictLargeN(false),
theFactorizationScaleFactor(1.0),
theRenormalizationScaleFactor(1.0),
theRenormalizationScaleFreeze(1.*GeV),
theFactorizationScaleFreeze(1.*GeV),
theVirtualitySplittingScale(false),
theCMWScheme(0),
presampling(false) {}
-DipoleSplittingKernel::~DipoleSplittingKernel() {}
-
-
// initialize static variable out of line
double DipoleSplittingKernel::theMaxPDFRatio = 1000000.;
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleSplittingKernel::persistentOutput(PersistentOStream & os) const {
os << theAlphaS << ounit(theScreeningScale,GeV)
<< theSplittingKinematics << thePDFRatio
<< thePresamplingPoints << theMaxtry << theFreezeGrid << theDetuning
<< theFlavour << theMCCheck << theStrictLargeN
<< theFactorizationScaleFactor
<< theRenormalizationScaleFactor
<< ounit(theRenormalizationScaleFreeze,GeV)
<< ounit(theFactorizationScaleFreeze,GeV)
<< theVirtualitySplittingScale<<theCMWScheme<<theUseThisKernel;
}
void DipoleSplittingKernel::persistentInput(PersistentIStream & is, int) {
is >> theAlphaS >> iunit(theScreeningScale,GeV)
>> theSplittingKinematics >> thePDFRatio
>> thePresamplingPoints >> theMaxtry >> theFreezeGrid >> theDetuning
>> theFlavour >> theMCCheck >> theStrictLargeN
>> theFactorizationScaleFactor
>> theRenormalizationScaleFactor
>> iunit(theRenormalizationScaleFreeze,GeV)
>> iunit(theFactorizationScaleFreeze,GeV)
>> theVirtualitySplittingScale>>theCMWScheme>>theUseThisKernel;
}
double DipoleSplittingKernel::alphaPDF(const DipoleSplittingInfo& split,
Energy optScale,
double rScaleFactor,
double fScaleFactor) const {
Energy pt = optScale == ZERO ? split.lastPt() : optScale;
Energy2 scale = ZERO;
if ( !virtualitySplittingScale() ) {
scale = sqr(pt) + sqr(theScreeningScale);
} else {
scale = sqr(splittingKinematics()->QFromPt(pt,split)) + sqr(theScreeningScale);
}
Energy2 fScale = sqr(theFactorizationScaleFactor*fScaleFactor)*scale;
fScale = max( fScale , sqr(factorizationScaleFreeze()) );
Energy2 rScale = sqr(theRenormalizationScaleFactor*rScaleFactor)*scale;
rScale = max( rScale , sqr(renormalizationScaleFreeze()) );
if(split.calcFixedExpansion()){
fScale = max( sqr(split.fixedScale()) , sqr(factorizationScaleFreeze()) );
rScale = max( sqr(split.fixedScale()) , sqr(renormalizationScaleFreeze()) );
}
double alphas = 1.0;
double pdf = 1.0;
// check if we are potentially reweighting and cache evaluations
bool evaluatePDF = true;
bool evaluateAlphaS = true;
bool variations =
!ShowerHandler::currentHandler()->showerVariations().empty() &&
!presampling;
if ( variations ) {
map<double,double>::const_iterator pit = thePDFCache.find(fScaleFactor);
evaluatePDF = (pit == thePDFCache.end());
if ( !evaluatePDF ) {
pdf = pit->second;
}
map<double,double>::const_iterator ait = theAlphaSCache.find(rScaleFactor);
evaluateAlphaS = (ait == theAlphaSCache.end());
if ( !evaluateAlphaS ) {
alphas = ait->second;
}
}
if ( evaluateAlphaS ){
if (theCMWScheme==0||split.calcFixedExpansion()) {
alphas = alphaS()->value(rScale);
}else if(theCMWScheme==1){
alphas = alphaS()->value(rScale);
alphas *=1.+(3.*(67./18.-1./6.*sqr(Constants::pi))
-5./9.*alphaS()->Nf(rScale))*
alphas/2./Constants::pi;
}else if(theCMWScheme==2){
double kg=exp(-(67.-3.*sqr(Constants::pi)-10/3*alphaS()->Nf(rScale))
/(33.-2.*alphaS()->Nf(rScale)));
Energy2 cmwscale2=max(kg*rScale, sqr(renormalizationScaleFreeze()) );
alphas = alphaS()->value(cmwscale2);
}else{
throw Exception()
<< "This CMW-Scheme is not implemented."
<< Exception::abortnow;
}
}
if ( evaluatePDF ) {
if ( split.index().initialStateEmitter() ) {
assert(pdfRatio());
pdf *=
split.lastEmitterZ() *
(*pdfRatio())(split.index().emitterPDF(), fScale,
split.index().emitterData(),split.emitterData(),
split.emitterX(),split.lastEmitterZ());
}
if ( split.index().initialStateSpectator() ) {
assert(pdfRatio());
pdf *=
split.lastSpectatorZ() *
(*pdfRatio())(split.index().spectatorPDF(), fScale,
split.index().spectatorData(),split.spectatorData(),
split.spectatorX(),split.lastSpectatorZ());
}
}
if ( evaluatePDF && variations ) {
thePDFCache[fScaleFactor] = min(pdf,theMaxPDFRatio);
}
if ( evaluateAlphaS && variations ) {
theAlphaSCache[rScaleFactor] = alphas;
}
double ret = min(pdf,theMaxPDFRatio)*
(split.calcFixedExpansion()?
1.:(alphas / (2.*Constants::pi)));
if ( ret < 0. )
ret = 0.;
return ret;
}
void DipoleSplittingKernel::accept(const DipoleSplittingInfo& split,
double, double,
map<string,double>& weights) const {
if ( ShowerHandler::currentHandler()->showerVariations().empty() )
return;
double reference = alphaPDF(split);
assert(reference > 0.);
for ( map<string,ShowerVariation>::const_iterator var =
ShowerHandler::currentHandler()->showerVariations().begin();
var != ShowerHandler::currentHandler()->showerVariations().end(); ++var ) {
if ( ( ShowerHandler::currentHandler()->firstInteraction()
&& var->second.firstInteraction ) ||
( !ShowerHandler::currentHandler()->firstInteraction()
&& var->second.secondaryInteractions ) ) {
double varied = alphaPDF(split,ZERO,
var->second.renormalizationScaleFactor,
var->second.factorizationScaleFactor);
if ( varied != reference ) {
map<string,double>::iterator wi = weights.find(var->first);
if ( wi != weights.end() )
wi->second *= varied/reference;
else
weights[var->first] = varied/reference;
}
}
}
}
void DipoleSplittingKernel::veto(const DipoleSplittingInfo& split,
double p, double r,
map<string,double>& weights) const {
if ( ShowerHandler::currentHandler()->showerVariations().empty() )
return;
double reference = alphaPDF(split);
// this is dangerous, but we have no other choice currently -- need to
// carefully check for the effects; the assumption is that if the central
// one ius zero, then so will be the variations.
if ( reference == 0.0 )
return;
for ( map<string,ShowerVariation>::const_iterator var =
ShowerHandler::currentHandler()->showerVariations().begin();
var != ShowerHandler::currentHandler()->showerVariations().end(); ++var ) {
if ( ( ShowerHandler::currentHandler()->firstInteraction()
&& var->second.firstInteraction ) ||
( !ShowerHandler::currentHandler()->firstInteraction()
&& var->second.secondaryInteractions ) ) {
double varied = alphaPDF(split,ZERO,
var->second.renormalizationScaleFactor,
var->second.factorizationScaleFactor);
if ( varied != reference ) {
map<string,double>::iterator wi = weights.find(var->first);
if ( wi != weights.end() )
wi->second *= (r - varied*p/reference) / (r-p);
else
weights[var->first] = (r - varied*p/reference) / (r-p);
}
}
}
}
AbstractClassDescription<DipoleSplittingKernel>
DipoleSplittingKernel::initDipoleSplittingKernel;
// Definition of the static class description member.
void DipoleSplittingKernel::Init() {
static ClassDocumentation<DipoleSplittingKernel> documentation
("DipoleSplittingKernel is the base class for all kernels "
"used within the dipole shower.");
static Reference<DipoleSplittingKernel,AlphaSBase> interfaceAlphaS
("AlphaS",
"The strong coupling to be used by this splitting kernel.",
&DipoleSplittingKernel::theAlphaS, false, false, true, true, false);
static Parameter<DipoleSplittingKernel,Energy> interfaceScreeningScale
("ScreeningScale",
"A colour screening scale",
&DipoleSplittingKernel::theScreeningScale, GeV, 0.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Reference<DipoleSplittingKernel,DipoleSplittingKinematics>
interfaceSplittingKinematics
("SplittingKinematics",
"The splitting kinematics to be used by this splitting kernel.",
&DipoleSplittingKernel::theSplittingKinematics, false, false, true, false, false);
static Reference<DipoleSplittingKernel,PDFRatio> interfacePDFRatio
("PDFRatio",
"Set the optional PDF ratio object to evaluate this kernel",
&DipoleSplittingKernel::thePDFRatio, false, false, true, true, false);
static Parameter<DipoleSplittingKernel,unsigned long> interfacePresamplingPoints
("PresamplingPoints",
"The number of points used to presample this kernel.",
&DipoleSplittingKernel::thePresamplingPoints, 2000, 1, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleSplittingKernel,unsigned long> interfaceMaxtry
("Maxtry",
"The maximum number of attempts to generate a splitting.",
&DipoleSplittingKernel::theMaxtry, 10000, 1, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleSplittingKernel,unsigned long> interfaceFreezeGrid
("FreezeGrid",
"",
&DipoleSplittingKernel::theFreezeGrid, 500000, 1, 0,
false, false, Interface::lowerlim);
static Reference<DipoleSplittingKernel,ParticleData> interfaceFlavour
("Flavour",
"Set the flavour to be produced if ambiguous.",
&DipoleSplittingKernel::theFlavour, false, false, true, true, false);
static Reference<DipoleSplittingKernel,DipoleMCCheck> interfaceMCCheck
("MCCheck",
"[debug option] MCCheck",
&DipoleSplittingKernel::theMCCheck, false, false, true, true, false);
interfaceMCCheck.rank(-1);
static Switch<DipoleSplittingKernel,bool> interfaceStrictLargeN
("StrictLargeN",
"Work in a strict large-N limit.",
&DipoleSplittingKernel::theStrictLargeN, false, false, false);
static SwitchOption interfaceStrictLargeNYes
(interfaceStrictLargeN,
"Yes",
"Replace C_F -> C_A/2 where present",
true);
static SwitchOption interfaceStrictLargeNNo
(interfaceStrictLargeN,
"No",
"Keep C_F=4/3",
false);
interfaceStrictLargeN.rank(-2);
static Switch<DipoleSplittingKernel,unsigned int> interfaceCMWScheme
("CMWScheme",
"Use the CMW Scheme related Kg expression to the splitting",
&DipoleSplittingKernel::theCMWScheme, 0, false, false);
static SwitchOption interfaceCMWSchemeNo
(interfaceCMWScheme,"No","No CMW-Scheme", 0);
static SwitchOption interfaceCMWSchemeLinear
(interfaceCMWScheme,"Linear",
"Linear CMW multiplication: alpha_s(q) -> alpha_s(q)(1+K_g*alpha_s(q)/2pi )",1);
static SwitchOption interfaceCMWSchemeFactor
(interfaceCMWScheme,"Factor",
"Use factor in alpha_s argument: alpha_s(q) -> alpha_s(k_g*q) with kfac=exp(-(67-3pi^2-10/3*Nf)/(33-2Nf)) ",2);
static Parameter<DipoleSplittingKernel,double> interfaceFactorizationScaleFactor
("FactorizationScaleFactor",
"The factorization scale factor.",
&DipoleSplittingKernel::theFactorizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
interfaceFactorizationScaleFactor.rank(-2);
static Parameter<DipoleSplittingKernel,double> interfaceRenormalizationScaleFactor
("RenormalizationScaleFactor",
"The renormalization scale factor.",
&DipoleSplittingKernel::theRenormalizationScaleFactor, 1.0, 0.0, 0,
false, false, Interface::lowerlim);
interfaceRenormalizationScaleFactor.rank(-2);
static Parameter<DipoleSplittingKernel,Energy> interfaceRenormalizationScaleFreeze
("RenormalizationScaleFreeze",
"The freezing scale for the renormalization scale.",
&DipoleSplittingKernel::theRenormalizationScaleFreeze,
GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<DipoleSplittingKernel,Energy> interfaceFactorizationScaleFreeze
("FactorizationScaleFreeze",
"The freezing scale for the factorization scale.",
&DipoleSplittingKernel::theFactorizationScaleFreeze, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Switch<DipoleSplittingKernel,bool> interfaceVirtualitySplittingScale
("VirtualitySplittingScale",
"Use the virtuality as the splitting scale.",
&DipoleSplittingKernel::theVirtualitySplittingScale, false, false, false);
static SwitchOption interfaceVirtualitySplittingScaleYes
(interfaceVirtualitySplittingScale,
"Yes",
"Use vrituality.",
true);
static SwitchOption interfaceVirtualitySplittingScaleNo
(interfaceVirtualitySplittingScale,
"No",
"Use transverse momentum.",
false);
static Parameter<DipoleSplittingKernel,double> interfaceDetuning
("Detuning",
"A value to detune the overestimate kernel.",
&DipoleSplittingKernel::theDetuning, 1.0, 1.0, 0,
false, false, Interface::lowerlim);
static Switch<DipoleSplittingKernel,bool> interfaceUseThisKernel
("UseKernel",
"Turn On and of the Kernel.",
&DipoleSplittingKernel::theUseThisKernel, true, false, false);
static SwitchOption interfaceUseThisKernelYes
(interfaceUseThisKernel,
"Yes",
"Use this Kernel.",
true);
static SwitchOption interfaceUseThisKernelNo
(interfaceUseThisKernel,
"No",
"Dont use this Kernel.",
false);
}
diff --git a/Shower/Dipole/Kernels/DipoleSplittingKernel.h b/Shower/Dipole/Kernels/DipoleSplittingKernel.h
--- a/Shower/Dipole/Kernels/DipoleSplittingKernel.h
+++ b/Shower/Dipole/Kernels/DipoleSplittingKernel.h
@@ -1,546 +1,538 @@
// -*- C++ -*-
//
// DipoleSplittingKernel.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_DipoleSplittingKernel_H
#define HERWIG_DipoleSplittingKernel_H
//
// This is the declaration of the DipoleSplittingKernel class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/StandardModel/AlphaSBase.h"
#include "ThePEG/PDF/PDF.h"
#include "Herwig/Shower/Dipole/Utility/PDFRatio.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
#include "Herwig/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h"
#include "ThePEG/EventRecord/RhoDMatrix.h"
#include "Herwig/Decay/DecayMatrixElement.h"
#include "Herwig/Decay/TwoBodyDecayMatrixElement.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief DipoleSplittingKernel is the base class for all kernels
* used within the dipole shower.
*
* @see \ref DipoleSplittingKernelInterfaces "The interfaces"
* defined for DipoleSplittingKernel.
*/
class DipoleSplittingKernel: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
DipoleSplittingKernel();
- /**
- * The destructor.
- */
- virtual ~DipoleSplittingKernel();
- //@}
-
public:
/**
* Return the alpha_s to be used
*/
Ptr<AlphaSBase>::tptr alphaS() const { return theAlphaS; }
/**
* Set the alpha_s to be used
*/
void alphaS(Ptr<AlphaSBase>::tptr ap) { theAlphaS = ap; }
/**
* Return the splitting kinematics object
*/
Ptr<DipoleSplittingKinematics>::tptr splittingKinematics() const {
return theSplittingKinematics;
}
/**
* Return the mc check object
*/
Ptr<DipoleMCCheck>::ptr mcCheck() const { return theMCCheck; }
/**
* Set the splitting kinematics object
*/
void splittingKinematics(Ptr<DipoleSplittingKinematics>::tptr sp) {
theSplittingKinematics = sp;
}
/**
* Return the PDFRatio object
*/
Ptr<PDFRatio>::tptr pdfRatio() const { return thePDFRatio; }
/**
* Set the PDFRatio object
*/
void pdfRatio(Ptr<PDFRatio>::tptr sp) { thePDFRatio = sp; }
/**
* Return the number of additional parameter
* random variables needed to evaluate this kernel
* except the momentum fractions of incoming partons.
* These will be accessible through the
* lastSplittingParameters() container of the splitting
* info object.
*/
virtual int nDimAdditional() const { return 0; }
/**
* Set the freezing value for the renormalization scale
*/
void renormalizationScaleFreeze(Energy s) { theRenormalizationScaleFreeze = s; }
/**
* Set the freezing value for the factorization scale
*/
void factorizationScaleFreeze(Energy s) { theFactorizationScaleFreeze = s; }
/**
* Get the freezing value for the renormalization scale
*/
Energy renormalizationScaleFreeze() const { return theRenormalizationScaleFreeze; }
/**
* Get the freezing value for the factorization scale
*/
Energy factorizationScaleFreeze() const { return theFactorizationScaleFreeze; }
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const = 0;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const = 0;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const = 0;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const = 0;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const = 0;
/**
* Return the flavour produced, if this cannot
* be determined from the dipole.
*/
PDPtr flavour() const { return theFlavour; }
/**
* Return true, if this splitting kernel is supposed to work in a
* strict large-N limit, i.e. replacing C_F by C_A/2
*/
bool strictLargeN() const { return theStrictLargeN; }
public:
/**
* Inform this splitting kernel, that it is being
* presampled until a call to stopPresampling
*/
virtual void startPresampling(const DipoleIndex&) {
presampling = true;
}
/**
* Inform this splitting kernel, that it is not being
* presampled until a call to startPresampling
*/
virtual void stopPresampling(const DipoleIndex&) {
presampling = false;
}
/**
* Return the number of points to presample this
* splitting generator.
*/
unsigned long presamplingPoints() const { return thePresamplingPoints; }
/**
* Return the maximum number of trials
* to generate a splitting.
*/
unsigned long maxtry() const { return theMaxtry; }
/**
* Return the number of accepted points after which the grid should
* be frozen
*/
unsigned long freezeGrid() const { return theFreezeGrid; }
/**
* Set the number of accepted points after which the grid should
* be frozen
*/
void freezeGrid(unsigned long n) { theFreezeGrid = n; }
/**
* Set a detuning factor to be applied to the sampling overestimate kernel
*/
void detuning(double d) { theDetuning = d; }
/**
* Return the detuning factor applied to the sampling overestimate kernel
*/
double detuning() const { return theDetuning; }
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const = 0;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const = 0;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) const = 0;
/**
* Clear the alphaPDF cache
*/
void clearAlphaPDFCache() const {
theAlphaSCache.clear();
thePDFCache.clear();
}
/**
* Update the variations vector at the given splitting using the indicated
* kernel and overestimate values.
*/
virtual void accept(const DipoleSplittingInfo&, double, double, map<string,double>&) const;
/**
* Update the variations vector at the given splitting using the indicated
* kernel and overestimate values.
*/
virtual void veto(const DipoleSplittingInfo&, double, double, map<string,double>&) const;
/**
* Return true, if this kernel is capable of
* delivering an overestimate to the kernel, and
* of inverting the integral over the overestimate
* w.r.t. the phasepsace provided by the given
* DipoleSplittingInfo object.
*/
virtual bool haveOverestimate(const DipoleSplittingInfo&) const { return false; }
/**
* Return the overestimate to this splitting kernel
* for the given dipole splitting.
*/
virtual double overestimate(const DipoleSplittingInfo&) const { return -1.; }
/**
* Invert the integral over the overestimate
* w.r.t. the phasepsace provided by the given
* DipoleSplittingInfo object to equal
* the given value.
*/
virtual double invertOverestimateIntegral(const DipoleSplittingInfo&, double) const {
return -1.;
}
/**
* .
*/
bool useThisKernel() const {
return theUseThisKernel;
}
public:
/**
* Get the factorization scale factor
*/
double factorizationScaleFactor() const { return theFactorizationScaleFactor; }
/**
* Set the factorization scale factor
*/
void factorizationScaleFactor(double f) { theFactorizationScaleFactor = f; }
/**
* Get the renormalization scale factor
*/
double renormalizationScaleFactor() const { return theRenormalizationScaleFactor; }
/**
* Set the renormalization scale factor
*/
void renormalizationScaleFactor(double f) { theRenormalizationScaleFactor = f; }
/**
* Return the CMW sheme used by the kernel
*/
unsigned int cmwScheme() const {return theCMWScheme;}
protected:
/**
* Return the common factor of (alphas/2pi)*(pdf ratio)
*/
double alphaPDF(const DipoleSplittingInfo&,
Energy optScale = ZERO,
double rScaleFactor = 1.0,
double fScaleFactor = 1.0) const;
/**
* Return true, if the virtuality of the splitting should be used as the
* argument of alphas rather than the pt
*/
bool virtualitySplittingScale() const { return theVirtualitySplittingScale; }
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).
private:
/**
* The alpha_s to be used.
*/
Ptr<AlphaSBase>::ptr theAlphaS;
/**
* An optional 'colour screening' scale
* for alternative intrinsic pt generation.
*/
Energy theScreeningScale;
/**
* The splitting kinematics to be used.
*/
Ptr<DipoleSplittingKinematics>::ptr theSplittingKinematics;
/**
* An optional PDF ratio object to be used
* when evaluating this kernel.
*/
Ptr<PDFRatio>::ptr thePDFRatio;
/**
* The number of points to presample this
* splitting generator.
*/
unsigned long thePresamplingPoints;
/**
* The maximum number of trials
* to generate a splitting.
*/
unsigned long theMaxtry;
/**
* The maximum value for any pdf ratio.
* TODO: JB:Should this be an interfaced value? Is there a reasobable case where it should be allowed to be bigger than 1000000.?
*/
static double theMaxPDFRatio;
/**
* 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;
/**
* The flavour produced, if this cannot
* be determined from the dipole.
*/
PDPtr theFlavour;
/**
* Pointer to a check histogram object
*/
Ptr<DipoleMCCheck>::ptr theMCCheck;
/**
* True, if this splitting kernel is supposed to work in a
* strict large-N limit, i.e. replacing C_F by C_A/2
*/
bool theStrictLargeN;
/**
* The factorization scale factor.
*/
double theFactorizationScaleFactor;
/**
* The renormalization scale factor.
*/
double theRenormalizationScaleFactor;
/**
* A freezing value for the renormalization scale
*/
Energy theRenormalizationScaleFreeze;
/**
* A freezing value for the factorization scale
*/
Energy theFactorizationScaleFreeze;
/**
* True, if the virtuality of the splitting should be used as the
* argument of alphas rather than the pt
*/
bool theVirtualitySplittingScale;
/**
* Implementing CMW in the kernels.
**/
unsigned int theCMWScheme=0;
/**
* Cache for alphas evaluations
*/
mutable map<double,double> theAlphaSCache;
/**
* Cache for PDF evaluations
*/
mutable map<double,double> thePDFCache;
/**
* True, if we are presampling
*/
bool presampling;
/**
* True, if the kernel should be used
*/
bool theUseThisKernel = true;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is an abstract class with persistent data.
*/
static AbstractClassDescription<DipoleSplittingKernel> initDipoleSplittingKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DipoleSplittingKernel & operator=(const DipoleSplittingKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of DipoleSplittingKernel. */
template <>
struct BaseClassTrait<Herwig::DipoleSplittingKernel,1> {
/** Typedef of the first base class of DipoleSplittingKernel. */
typedef HandlerBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the DipoleSplittingKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::DipoleSplittingKernel>
: public ClassTraitsBase<Herwig::DipoleSplittingKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::DipoleSplittingKernel"; }
/**
* The name of a file containing the dynamic library where the class
* DipoleSplittingKernel is implemented. It may also include several, space-separated,
* libraries if the class DipoleSplittingKernel 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_DipoleSplittingKernel_H */
diff --git a/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.cc
@@ -1,196 +1,194 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FFMgx2ggxDipoleKernel class.
//
#include "FFMgx2ggxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FFMgx2ggxDipoleKernel::FFMgx2ggxDipoleKernel()
: DipoleSplittingKernel(){}
-FFMgx2ggxDipoleKernel::~FFMgx2ggxDipoleKernel() {}
-
IBPtr FFMgx2ggxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FFMgx2ggxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FFMgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() != ZERO &&
!ind.initialStateEmitter() && !ind.initialStateSpectator() &&
!ind.incomingDecayEmitter() && !ind.incomingDecaySpectator();
}
bool FFMgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emitter(b)->id() == ParticleID::g &&
sk.emission(b)->id() == ParticleID::g &&
abs(spectator(a)->mass()) == abs(sk.spectator(b)->mass());
}
tcPDPtr FFMgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FFMgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FFMgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FFMgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
// Sudakov parameterisation variables,
// needed to calculate y.
double z = split.lastZ();
Energy pt = split.lastPt();
// Construct mass squared variables
Energy2 Qijk = sqr(split.scale());
Energy2 mk2 = sqr(split.spectatorMass());
Energy2 sbar = Qijk - mk2;
// Calculate y
double y = sqr(pt) / sbar / z / (1.-z);
double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
double viji = 1.;
// zi, used in dipole splitting kernel
double zi = split.lastSplittingParameters()[0];
double zip = 0.5*(1.+viji*vijk);
double zim = 0.5*(1.-viji*vijk);
// how to choose kappa?
double kappa = 0.;
double S1=1./(1.-zi*(1.-y));
double S2=1./(1.-(1.-zi)*(1.-y));
double NS=(zi*(1.-zi)-(1.-kappa)*zip*zim-2.)/vijk;
if( theAsymmetryOption == 0 ){
ret *= 3.*( S1 + 0.5 * NS);
}else if ( theAsymmetryOption == 1 ){
ret *= 3.*zi*( S1 +S2 + NS );
}else{
ret *= 3.*0.5*( S1 + S2 + NS );
}
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FFMgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
// Need variables for the AP kernels
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
//double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) - 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp))/max ) );
distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
return distPhiDep;
}
DecayMEPtr FFMgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
// Need variables for the AP kernels
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
(*kernelPhiDep)(0,2,2) = 0;
(*kernelPhiDep)(2,0,0) = 0;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFMgx2ggxDipoleKernel::persistentOutput(PersistentOStream & os) const {
os << theAsymmetryOption;
}
void FFMgx2ggxDipoleKernel::persistentInput(PersistentIStream & is, int) {
is >> theAsymmetryOption;
}
ClassDescription<FFMgx2ggxDipoleKernel> FFMgx2ggxDipoleKernel::initFFMgx2ggxDipoleKernel;
// Definition of the static class description member.
void FFMgx2ggxDipoleKernel::Init() {
static ClassDocumentation<FFMgx2ggxDipoleKernel> documentation
("FFMgx2ggxDipoleKernel");
static Parameter<FFMgx2ggxDipoleKernel,int> interfacetheAsymmetryOption
("AsymmetryOption",
"The asymmetry option for final state gluon spliitings.",
&FFMgx2ggxDipoleKernel::theAsymmetryOption, 1, 0, 0,
false, false, Interface::lowerlim);
}
diff --git a/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFMgx2ggxDipoleKernel.h
@@ -1,198 +1,190 @@
// -*- C++ -*-
#ifndef HERWIG_FFMgx2ggxDipoleKernel_H
#define HERWIG_FFMgx2ggxDipoleKernel_H
//
// This is the declaration of the FFMgx2ggxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll, Stephen Webster
*
* \brief FFMgx2ggxDipoleKernel implements the g -> gg
* splitting off a final-final dipole
*
*/
class FFMgx2ggxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFMgx2ggxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FFMgx2ggxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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:
/**
* Asymmetry option for final state gluon splittings.
*/
int theAsymmetryOption=1;
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FFMgx2ggxDipoleKernel> initFFMgx2ggxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFMgx2ggxDipoleKernel & operator=(const FFMgx2ggxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FFMgx2ggxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FFMgx2ggxDipoleKernel,1> {
/** Typedef of the first base class of FFMgx2ggxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FFMgx2ggxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FFMgx2ggxDipoleKernel>
: public ClassTraitsBase<Herwig::FFMgx2ggxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FFMgx2ggxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FFMgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FFMgx2ggxDipoleKernel 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_FFMgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.cc
@@ -1,195 +1,193 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FFMgx2qqxDipoleKernel class.
//
#include "FFMgx2qqxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FFMgx2qqxDipoleKernel::FFMgx2qqxDipoleKernel()
: DipoleSplittingKernel() {}
-FFMgx2qqxDipoleKernel::~FFMgx2qqxDipoleKernel() {}
-
IBPtr FFMgx2qqxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FFMgx2qqxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FFMgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
!( ind.spectatorData()->mass() == ZERO &&
flavour()->mass() == ZERO ) &&
!ind.initialStateEmitter() && !ind.initialStateSpectator() &&
!ind.incomingDecayEmitter() && !ind.incomingDecaySpectator();
}
bool FFMgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emitter(b)->id() + sk.emission(b)->id() == 0 &&
abs(sk.emitter(b)->id()) < 6 &&
emitter(a)->id() == sk.emitter(b)->id() &&
abs(sk.spectator(b)->mass()) == abs(spectator(a)->mass());
}
tcPDPtr FFMgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6);
return flavour();
}
tcPDPtr FFMgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6);
return flavour()->CC();
}
tcPDPtr FFMgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FFMgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
// Sudakov parameterisation variables,
// needed to calculate y.
double z = split.lastZ();
Energy pt = split.lastPt();
// Construct mass squared variables
Energy2 Qijk = sqr(split.scale());
Energy2 mi2 = sqr(split.emitterData()->mass());
Energy2 mj2 = mi2;
Energy2 mk2 = sqr(split.spectatorMass());
Energy2 sbar = Qijk - mi2 - mj2 - mk2;
// Calculate y
double y = (sqr(pt) + sqr(1.-z)*mi2 + sqr(z)*mj2) / sbar / z / (1.-z);
// zi, used in dipole splitting kernel
double zi = split.lastSplittingParameters()[0];
double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
double viji = sqrt( sqr(sbar*y) - 4.*sqr(mi2) ) / (sbar*y + 2.*mi2);
double zip = 0.5*(1.+viji*vijk);
double zim = 0.5*(1.-viji*vijk);
// how to choose kappa??
double kappa = 0.;
ret *= 0.25 / vijk *
( 1. - 2.*( zi*(1.-zi) - (1.-kappa)*zip*zim
- kappa*mi2 / ( 2.*mi2 + (Qijk - 2.*mi2 - mk2)*y) ) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FFMgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
// Need variables for the AP kernels
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
Energy2 mi2 = sqr(dInfo.emitterData()->mass());
// Altarelli-Parisi spin-indexed kernels:
double ratio = mi2 / ( mi2 + sqr(pt) );
double root = sqrt(1.-ratio);
double v_AP_ppp = sqrt(ratio);
double v_AP_ppm = z*root;
double v_AP_pmp = -(1.-z)*root;
//double v_AP_mmm = v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) + 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp) )/max ) );
distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
return distPhiDep;
}
DecayMEPtr FFMgx2qqxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
// Need variables for the AP kernels
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
Energy2 mi2 = sqr(dInfo.emitterData()->mass());
// Altarelli-Parisi spin-indexed kernels:
double ratio = mi2 / ( mi2 + sqr(pt) );
double root = sqrt(1.-ratio);
double v_AP_ppp = sqrt(ratio);
double v_AP_ppm = z*root;
double v_AP_pmp = -(1.-z)*root;
double v_AP_mmm = v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm;
(*kernelPhiDep)(2,1,1) = v_AP_ppp;
(*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
(*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
(*kernelPhiDep)(0,1,1) = 0.;
(*kernelPhiDep)(2,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFMgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void FFMgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FFMgx2qqxDipoleKernel>
FFMgx2qqxDipoleKernel::initFFMgx2qqxDipoleKernel;
// Definition of the static class description member.
void FFMgx2qqxDipoleKernel::Init() {
static ClassDocumentation<FFMgx2qqxDipoleKernel> documentation
("FFMgx2qqxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFMgx2qqxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_FFMgx2qqxDipoleKernel_H
#define HERWIG_FFMgx2qqxDipoleKernel_H
//
// This is the declaration of the FFMgx2qqxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll, Stephen Webster
*
* \brief FFMgx2qqxDipoleKernel implements the g -> qqbar
* splitting off a final-final dipole
*
*/
class FFMgx2qqxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFMgx2qqxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FFMgx2qqxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FFMgx2qqxDipoleKernel> initFFMgx2qqxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFMgx2qqxDipoleKernel & operator=(const FFMgx2qqxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FFMgx2qqxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FFMgx2qqxDipoleKernel,1> {
/** Typedef of the first base class of FFMgx2qqxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FFMgx2qqxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FFMgx2qqxDipoleKernel>
: public ClassTraitsBase<Herwig::FFMgx2qqxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FFMgx2qqxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FFMgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FFMgx2qqxDipoleKernel 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_FFMgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.cc
@@ -1,169 +1,167 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FFMqx2qgxDipoleKernel class.
//
#include "FFMqx2qgxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FFMqx2qgxDipoleKernel::FFMqx2qgxDipoleKernel()
: DipoleSplittingKernel() {}
-FFMqx2qgxDipoleKernel::~FFMqx2qgxDipoleKernel() {}
-
IBPtr FFMqx2qgxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FFMqx2qgxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FFMqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
abs(ind.emitterData()->id()) < 7 &&
// 2012-05-01
abs(ind.emitterData()->id()) == abs(flavour()->id()) &&
!( ind.emitterData()->mass() == ZERO &&
ind.spectatorData()->mass() == ZERO ) &&
!ind.initialStateEmitter() && !ind.initialStateSpectator() &&
!ind.incomingDecayEmitter() && !ind.incomingDecaySpectator();
}
bool FFMqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emission(b)->id() == ParticleID::g &&
abs(sk.emitter(b)->id()) < 7 &&
abs(sk.emitter(b)->mass()) == abs(emitter(a)->mass()) &&
abs(sk.spectator(b)->mass()) == abs(spectator(a)->mass());
}
// 2012-05-01
tcPDPtr FFMqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
assert(flavour());
assert(abs(flavour()->id())<7);
return ind.emitterData()->id() > 0 ?
(tcPDPtr) flavour() : (tcPDPtr) flavour()->CC();
}
tcPDPtr FFMqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FFMqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FFMqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
// Sudakov parameterisation variables,
// needed to calculate y.
double z = split.lastZ();
Energy pt = split.lastPt();
// Construct mass squared variables
// Note for q->qg can use the emitterMass
// (i.e. mass of emitter before splitting = mass of emitter after)
Energy2 Qijk = sqr(split.scale());
Energy2 mi2 = sqr(split.emitterMass());
Energy2 mk2 = sqr(split.spectatorMass());
Energy2 sbar = Qijk - mi2 - mk2;
// Calculate y
double y = (sqr(pt) + sqr(1.-z)*mi2) / sbar / z / (1.-z);
// zi, used in dipole splitting kernel
double zi = split.lastSplittingParameters()[0];
double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
double vtilde = sqrt( sqr(Qijk) + sqr(mi2) + sqr(mk2)
- 2.*(mi2*Qijk + mk2*Qijk + mi2*mk2) ) / sbar;
ret *= (!strictLargeN() ? 4./3. : 3./2.)*
( 2./(1.-zi*(1.-y)) - vtilde/vijk*( 1. + zi + 2.*mi2/sbar/y ) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FFMqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
// No dependence on the spin density matrix,
// dependence on off-diagonal terms cancels.
return {{ {0, 1.} }};
}
DecayMEPtr FFMqx2qgxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
// Need variables for the AP kernels
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
Energy mi = dInfo.emitterMass();
// Altarelli-Parisi spin-indexed kernels:
Energy den = sqrt(sqr(mi)*sqr(1.-z) + sqr(pt));
double v_AP_ppp = pt / den / sqrt(1.-z);
double v_AP_ppm = - z * v_AP_ppp ;
double v_AP_pmp = mi*(1.-z)*sqrt(1.-z) / den ;
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -1 or -1/2, 1=+1/2, 2 = +1
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = v_AP_mpm;
(*kernelPhiDep)(1,0,2) = v_AP_pmp;
(*kernelPhiDep)(0,1,2) = 0.;
(*kernelPhiDep)(1,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFMqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void FFMqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FFMqx2qgxDipoleKernel> FFMqx2qgxDipoleKernel::initFFMqx2qgxDipoleKernel;
// Definition of the static class description member.
void FFMqx2qgxDipoleKernel::Init() {
static ClassDocumentation<FFMqx2qgxDipoleKernel> documentation
("FFMqx2qgxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFMqx2qgxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_FFMqx2qgxDipoleKernel_H
#define HERWIG_FFMqx2qgxDipoleKernel_H
//
// This is the declaration of the FFMqx2qgxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll, Stephen Webster
*
* \brief FFMqx2qgxDipoleKernel implements the q -> qg
* splitting off a final-final dipole
*
*/
class FFMqx2qgxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFMqx2qgxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FFMqx2qgxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FFMqx2qgxDipoleKernel> initFFMqx2qgxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFMqx2qgxDipoleKernel & operator=(const FFMqx2qgxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FFMqx2qgxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FFMqx2qgxDipoleKernel,1> {
/** Typedef of the first base class of FFMqx2qgxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FFMqx2qgxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FFMqx2qgxDipoleKernel>
: public ClassTraitsBase<Herwig::FFMqx2qgxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FFMqx2qgxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FFMqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FFMqx2qgxDipoleKernel 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_FFMqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.cc
@@ -1,173 +1,171 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FFgx2ggxDipoleKernel class.
//
#include "FFgx2ggxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FFgx2ggxDipoleKernel::FFgx2ggxDipoleKernel()
: DipoleSplittingKernel(){}
-FFgx2ggxDipoleKernel::~FFgx2ggxDipoleKernel() {}
-
IBPtr FFgx2ggxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FFgx2ggxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FFgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() == ZERO &&
!ind.initialStateEmitter() && !ind.initialStateSpectator();
}
#ifndef NDEBUG
bool FFgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
#else
bool FFgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& ,
#endif
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emitter(b)->id() == ParticleID::g &&
sk.emission(b)->id() == ParticleID::g;
}
tcPDPtr FFgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FFgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FFgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FFgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double y = sqr(split.lastPt() / split.scale()) / (z*(1.-z));
double S1=1./(1.-z*(1.-y));
double S2=1./(1.-(1.-z)*(1.-y));
double NS=(-2 + z*(1.-z));
if( theAsymmetryOption == 0 ){
ret *= 3.*( S1 + 0.5 * NS);
}else if ( theAsymmetryOption == 1 ){
ret *= 3.*z*( S1 +S2 + NS );
}else{
ret *= 3.*0.5*( S1 + S2 + NS );
}
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FFgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
//double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) - 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp))/max ) );
distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
return distPhiDep;
}
DecayMEPtr FFgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
(*kernelPhiDep)(0,2,2) = 0;
(*kernelPhiDep)(2,0,0) = 0;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFgx2ggxDipoleKernel::persistentOutput(PersistentOStream & os) const {
os << theAsymmetryOption;
}
void FFgx2ggxDipoleKernel::persistentInput(PersistentIStream & is, int) {
is >> theAsymmetryOption;
}
ClassDescription<FFgx2ggxDipoleKernel> FFgx2ggxDipoleKernel::initFFgx2ggxDipoleKernel;
// Definition of the static class description member.
void FFgx2ggxDipoleKernel::Init() {
static ClassDocumentation<FFgx2ggxDipoleKernel> documentation
("FFgx2ggxDipoleKernel");
static Parameter<FFgx2ggxDipoleKernel,int> interfacetheAsymmetryOption
("AsymmetryOption",
"The asymmetry option for final state gluon spliitings.",
&FFgx2ggxDipoleKernel::theAsymmetryOption, 1, 0, 0,
false, false, Interface::lowerlim);
}
diff --git a/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFgx2ggxDipoleKernel.h
@@ -1,198 +1,190 @@
// -*- C++ -*-
#ifndef HERWIG_FFgx2ggxDipoleKernel_H
#define HERWIG_FFgx2ggxDipoleKernel_H
//
// This is the declaration of the FFgx2ggxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief FFgx2ggxDipoleKernel implements the g -> gg
* splitting off a final-final dipole
*
*/
class FFgx2ggxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFgx2ggxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FFgx2ggxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FFgx2ggxDipoleKernel> initFFgx2ggxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFgx2ggxDipoleKernel & operator=(const FFgx2ggxDipoleKernel &) = delete;
/**
* Asymmetry option for final state gluon splittings.
*/
int theAsymmetryOption=1;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FFgx2ggxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FFgx2ggxDipoleKernel,1> {
/** Typedef of the first base class of FFgx2ggxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FFgx2ggxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FFgx2ggxDipoleKernel>
: public ClassTraitsBase<Herwig::FFgx2ggxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FFgx2ggxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FFgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FFgx2ggxDipoleKernel 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_FFgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.cc
@@ -1,158 +1,156 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FFgx2qqxDipoleKernel class.
//
#include "FFgx2qqxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FFgx2qqxDipoleKernel::FFgx2qqxDipoleKernel()
: DipoleSplittingKernel() {}
-FFgx2qqxDipoleKernel::~FFgx2qqxDipoleKernel() {}
-
IBPtr FFgx2qqxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FFgx2qqxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FFgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() == ZERO &&
flavour()->mass() == ZERO &&
!ind.initialStateEmitter() && !ind.initialStateSpectator();
}
#ifndef NDEBUG
bool FFgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
#else
bool FFgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& ,
#endif
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emitter(b)->id() + sk.emission(b)->id() == 0 &&
abs(sk.emitter(b)->id()) < 6 &&
sk.emitter(b)->mass() == ZERO;
}
tcPDPtr FFgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
return flavour();
}
tcPDPtr FFgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
return flavour()->CC();
}
tcPDPtr FFgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FFgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
ret *= .25 * ( 1. - 2.*z*(1.-z) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FFgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppm = z;
double v_AP_pmp = -(1.-z);
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppm) + sqr(v_AP_pmp)) + 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*( sqr(v_AP_ppm) + sqr(v_AP_pmp) )/max ) );
distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
return distPhiDep;
}
DecayMEPtr FFgx2qqxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppm = z;
double v_AP_pmp = -(1.-z);
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = 0.;
(*kernelPhiDep)(2,1,1) = 0.;
(*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
(*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
(*kernelPhiDep)(0,1,1) = 0.;
(*kernelPhiDep)(2,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void FFgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FFgx2qqxDipoleKernel> FFgx2qqxDipoleKernel::initFFgx2qqxDipoleKernel;
// Definition of the static class description member.
void FFgx2qqxDipoleKernel::Init() {
static ClassDocumentation<FFgx2qqxDipoleKernel> documentation
("FFgx2qqxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFgx2qqxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_FFgx2qqxDipoleKernel_H
#define HERWIG_FFgx2qqxDipoleKernel_H
//
// This is the declaration of the FFgx2qqxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief FFgx2qqxDipoleKernel implements the g -> qqbar
* splitting off a final-final dipole
*
*/
class FFgx2qqxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFgx2qqxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FFgx2qqxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FFgx2qqxDipoleKernel> initFFgx2qqxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFgx2qqxDipoleKernel & operator=(const FFgx2qqxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FFgx2qqxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FFgx2qqxDipoleKernel,1> {
/** Typedef of the first base class of FFgx2qqxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FFgx2qqxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FFgx2qqxDipoleKernel>
: public ClassTraitsBase<Herwig::FFgx2qqxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FFgx2qqxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FFgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FFgx2qqxDipoleKernel 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_FFgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.cc
@@ -1,139 +1,137 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FFqx2qgxDipoleKernel class.
//
#include "FFqx2qgxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FFqx2qgxDipoleKernel::FFqx2qgxDipoleKernel()
: DipoleSplittingKernel() {}
-FFqx2qgxDipoleKernel::~FFqx2qgxDipoleKernel() {}
-
IBPtr FFqx2qgxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FFqx2qgxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FFqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
abs(ind.emitterData()->id()) < 6 &&
ind.emitterData()->mass() == ZERO &&
ind.spectatorData()->mass() == ZERO &&
!ind.initialStateEmitter() && !ind.initialStateSpectator();
}
#ifndef NDEBUG
bool FFqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
#else
bool FFqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& ,
#endif
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emission(b)->id() == ParticleID::g &&
abs(sk.emitter(b)->id()) < 6 &&
sk.emitter(b)->mass() == ZERO;
}
tcPDPtr FFqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
return ind.emitterData();
}
tcPDPtr FFqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FFqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FFqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double y = sqr(split.lastPt() / split.scale()) / (z*(1.-z));
ret *= (!strictLargeN() ? 4./3. : 3./2.)*( 2./(1.-z*(1.-y)) - (1.+z) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FFqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
// No dependence on the spin density matrix,
// dependence on off-diagonal terms cancels.
return {{ {0, 1.} }};
}
DecayMEPtr FFqx2qgxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = sqrt( 1./(1.-z) );
double v_AP_ppm = -z/sqrt(1.-z);
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -1 or -1/2, 1=+1/2, 2 = +1
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = 0.;
(*kernelPhiDep)(1,0,2) = 0.;
(*kernelPhiDep)(0,1,2) = 0.;
(*kernelPhiDep)(1,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void FFqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FFqx2qgxDipoleKernel> FFqx2qgxDipoleKernel::initFFqx2qgxDipoleKernel;
// Definition of the static class description member.
void FFqx2qgxDipoleKernel::Init() {
static ClassDocumentation<FFqx2qgxDipoleKernel> documentation
("FFqx2qgxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FFqx2qgxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_FFqx2qgxDipoleKernel_H
#define HERWIG_FFqx2qgxDipoleKernel_H
//
// This is the declaration of the FFqx2qgxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief FFqx2qgxDipoleKernel implements the q -> qg
* splitting off a final-final dipole
*
*/
class FFqx2qgxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFqx2qgxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FFqx2qgxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FFqx2qgxDipoleKernel> initFFqx2qgxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFqx2qgxDipoleKernel & operator=(const FFqx2qgxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FFqx2qgxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FFqx2qgxDipoleKernel,1> {
/** Typedef of the first base class of FFqx2qgxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FFqx2qgxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FFqx2qgxDipoleKernel>
: public ClassTraitsBase<Herwig::FFqx2qgxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FFqx2qgxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FFqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FFqx2qgxDipoleKernel 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_FFqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.cc
@@ -1,220 +1,218 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FIMDecaygx2ggxDipoleKernel class.
//
#include "FIMDecaygx2ggxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FIMDecaygx2ggxDipoleKernel::FIMDecaygx2ggxDipoleKernel()
: DipoleSplittingKernel(){}
-FIMDecaygx2ggxDipoleKernel::~FIMDecaygx2ggxDipoleKernel() {}
-
IBPtr FIMDecaygx2ggxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FIMDecaygx2ggxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FIMDecaygx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.incomingDecaySpectator() && !ind.incomingDecayEmitter() &&
ind.emitterData()->id() == ParticleID::g &&
!(ind.spectatorData()->mass() == ZERO) &&
// Initial state here refers to the entire event
!ind.initialStateEmitter() && !ind.initialStateSpectator();
}
bool FIMDecaygx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emission(b)->id() == ParticleID::g &&
sk.emitter(b)->id() == ParticleID::g &&
abs(sk.spectator(b)->mass()) == abs(spectator(a)->mass());
}
tcPDPtr FIMDecaygx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FIMDecaygx2ggxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FIMDecaygx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FIMDecaygx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
// Sudakov parameterisation variables,
// needed to calculate y.
double z = split.lastZ();
Energy pt = split.lastPt();
// Construct mass squared variables
// Note for q->qg can use the emitterMass
// (i.e. mass of emitter before splitting = mass of emitter after)
Energy2 Qijk = sqr(split.scale());
Energy2 mk2 = sqr(split.recoilMass());
Energy2 sbar = Qijk - mk2;
// Note this should be the same as Qijk
Energy2 ma2 = sqr(split.spectatorMass());
// Calculate y
double y = sqr(pt) / sbar / z / (1.-z);
if( sqr(2.*mk2+sbar*(1.-y)) - 4.*mk2*Qijk < ZERO ){
generator()->logWarning( Exception()
<< "error in FIMDecayqx2qgxDipoleKernel::evaluate -- " <<
"mk2 " << mk2/GeV2 << " y " << y << Exception::warning );
return 0.0;
}
// zi, used in dipole splitting kernel
double zi = split.lastSplittingParameters()[0];
double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
double vtilde = 1.;
double viji = 1.;
double zip = 0.5*(1.+viji*vijk);
double zim = 0.5*(1.-viji*vijk);
// how to choose kappa?
double kappa = 0.;
double S1 = 0.5*3.*(2.*y + 1.)/((1.+y)-zi*(1.-y)) +
(!strictLargeN() ? 4./3. : 3./2.)*
y/(1.-zi*(1.-y)) * ( 2.*(2.*y + 1.)/((1.+y)-zi*(1.-y))
- (vtilde/vijk)*(2. + 2.*ma2/((1.-zi*(1.-y))*sbar)) );
double S2 = 0.5*3.*(2.*y + 1.)/((1.+y)-(1.-zi)*(1.-y)) +
(!strictLargeN() ? 4./3. : 3./2.)*
y/(1.-(1.-zi)*(1.-y)) * ( 2.*(2.*y + 1.)/((1.+y)-(1.-zi)*(1.-y))
- (vtilde/vijk)*(2. + 2.*ma2/((1.-(1.-zi)*(1.-y))*sbar)) );
double NS = 0.5*3.*(zi*(1.-zi)-(1.-kappa)*zip*zim - 2.)/vijk;
if( theAsymmetryOption == 0 ){
ret *= 2.*S1 + NS;
}else if ( theAsymmetryOption == 1 ){
ret *= 2.*zi*( S1 + S2 + NS );
}else{
ret *= S1 + S2 + NS;
}
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FIMDecaygx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo,
const RhoDMatrix& rho) const {
// Need variables for the AP kernels
double z = dInfo.lastSplittingParameters()[0];
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
//double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) - 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp))/max ) );
distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
return distPhiDep;
}
DecayMEPtr FIMDecaygx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
// Need variables for the AP kernels
double z = dInfo.lastSplittingParameters()[0];
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
(*kernelPhiDep)(0,2,2) = 0;
(*kernelPhiDep)(2,0,0) = 0;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIMDecaygx2ggxDipoleKernel::persistentOutput(PersistentOStream & os) const {
os<<theAsymmetryOption;
}
void FIMDecaygx2ggxDipoleKernel::persistentInput(PersistentIStream & is, int) {
is>>theAsymmetryOption;
}
ClassDescription<FIMDecaygx2ggxDipoleKernel> FIMDecaygx2ggxDipoleKernel::initFIMDecaygx2ggxDipoleKernel;
// Definition of the static class description member.
void FIMDecaygx2ggxDipoleKernel::Init() {
static ClassDocumentation<FIMDecaygx2ggxDipoleKernel> documentation
("FIMDecaygx2ggxDipoleKernel");
static Parameter<FIMDecaygx2ggxDipoleKernel,int> interfacetheAsymmetryOption
("AsymmetryOption",
"The asymmetry option for final state gluon spliitings.",
&FIMDecaygx2ggxDipoleKernel::theAsymmetryOption, 0, 0, 0,
false, false, Interface::lowerlim);
}
diff --git a/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIMDecaygx2ggxDipoleKernel.h
@@ -1,197 +1,189 @@
// -*- C++ -*-
#ifndef HERWIG_FIMDecaygx2ggxDipoleKernel_H
#define HERWIG_FIMDecaygx2ggxDipoleKernel_H
//
// This is the declaration of the FIMDecaygx2ggxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Stephen Webster
*
* \brief FIMDecaygx2ggxDipoleKernel implements the g -> gg
* splitting off a final-initial decay dipole and includes the
* contribution from the splitting of the intial / decay particle
*
*/
class FIMDecaygx2ggxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIMDecaygx2ggxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FIMDecaygx2ggxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIMDecaygx2ggxDipoleKernel> initFIMDecaygx2ggxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIMDecaygx2ggxDipoleKernel & operator=(const FIMDecaygx2ggxDipoleKernel &) = delete;
/**
* Asymmetry option for final state gluon splittings.
*/
int theAsymmetryOption=0;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIMDecaygx2ggxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FIMDecaygx2ggxDipoleKernel,1> {
/** Typedef of the first base class of FIMDecaygx2ggxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIMDecaygx2ggxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIMDecaygx2ggxDipoleKernel>
: public ClassTraitsBase<Herwig::FIMDecaygx2ggxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIMDecaygx2ggxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FIMDecaygx2ggxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FIMDecaygx2ggxDipoleKernel 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_FIMDecaygx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.cc
@@ -1,207 +1,205 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FIMDecaygx2qqxDipoleKernel class.
//
#include "FIMDecaygx2qqxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FIMDecaygx2qqxDipoleKernel::FIMDecaygx2qqxDipoleKernel()
: DipoleSplittingKernel() {}
-FIMDecaygx2qqxDipoleKernel::~FIMDecaygx2qqxDipoleKernel() {}
-
IBPtr FIMDecaygx2qqxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FIMDecaygx2qqxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FIMDecaygx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.incomingDecaySpectator() && !ind.incomingDecayEmitter() &&
ind.emitterData()->id() == ParticleID::g &&
!(ind.spectatorData()->mass() == ZERO) &&
// Initial state here refers to the entire event
!ind.initialStateEmitter() && !ind.initialStateSpectator();
}
bool FIMDecaygx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emitter(b)->id() + sk.emission(b)->id() == 0 &&
abs(sk.emitter(b)->id()) < 6 &&
emitter(a)->id() == sk.emitter(b)->id() &&
abs(sk.spectator(b)->mass()) == abs(spectator(a)->mass());
}
tcPDPtr FIMDecaygx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6);
return flavour();
}
tcPDPtr FIMDecaygx2qqxDipoleKernel::emission(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6);
return flavour()->CC();
}
tcPDPtr FIMDecaygx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FIMDecaygx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
// Sudakov parameterisation variables,
// needed to calculate y.
double z = split.lastZ();
Energy pt = split.lastPt();
// Construct mass squared variables
// Note for q->qg can use the emitterMass
// (i.e. mass of emitter before splitting = mass of emitter after)
Energy2 Qijk = sqr(split.scale());
Energy2 mi2 = sqr(split.emitterData()->mass());
Energy2 mj2 = mi2;
Energy2 mk2 = sqr(split.recoilMass());
Energy2 sbar = Qijk - mi2 - mj2 - mk2;
// Calculate y
double y = (sqr(pt) + sqr(1.-z)*mi2 + sqr(z)*mj2) / sbar / z / (1.-z);
if( sqr(2.*mk2+sbar*(1.-y)) - 4.*mk2*Qijk < ZERO ){
generator()->logWarning( Exception()
<< "error in FIMDecayqx2qgxDipoleKernel::evaluate -- " <<
"mk2 " << mk2/GeV2 << " mi2 " << mi2/GeV2 << " y " << y << Exception::warning );
return 0.0;
}
// zi, used in dipole splitting kernel
double zi = split.lastSplittingParameters()[0];
double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
double viji = sqrt( sqr(sbar*y) - 4.*sqr(mi2) ) / (sbar*y + 2.*mi2);
double zip = 0.5*(1.+viji*vijk);
double zim = 0.5*(1.-viji*vijk);
// how to choose kappa?
double kappa = 0.;
ret *= 0.25 / vijk
* ( 1. - 2.*( zi*(1.-zi) - (1.-kappa)*zip*zim - kappa*mi2/(2.*mi2 + sbar*y) ) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FIMDecaygx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo,
const RhoDMatrix& rho) const {
// Need variables for the AP kernels
double z = dInfo.lastSplittingParameters()[0];
Energy pt = dInfo.lastPt();
Energy2 mi2 = sqr(dInfo.emitterData()->mass());
// Altarelli-Parisi spin-indexed kernels:
double ratio = mi2 / ( mi2 + sqr(pt) );
double root = sqrt(1.-ratio);
double v_AP_ppp = sqrt(ratio);
double v_AP_ppm = z*root;
double v_AP_pmp = -(1.-z)*root;
// double v_AP_mmm = v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) + 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp) )/max ) );
distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
return distPhiDep;
}
DecayMEPtr FIMDecaygx2qqxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
// Need variables for the AP kernels
double z = dInfo.lastSplittingParameters()[0];
Energy pt = dInfo.lastPt();
Energy2 mi2 = sqr(dInfo.emitterData()->mass());
// Altarelli-Parisi spin-indexed kernels:
double ratio = mi2 / ( mi2 + sqr(pt) );
double root = sqrt(1.-ratio);
double v_AP_ppp = sqrt(ratio);
double v_AP_ppm = z*root;
double v_AP_pmp = -(1.-z)*root;
double v_AP_mmm = v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm;
(*kernelPhiDep)(2,1,1) = v_AP_ppp;;
(*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
(*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
(*kernelPhiDep)(0,1,1) = 0.;
(*kernelPhiDep)(2,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIMDecaygx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void FIMDecaygx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FIMDecaygx2qqxDipoleKernel> FIMDecaygx2qqxDipoleKernel::initFIMDecaygx2qqxDipoleKernel;
// Definition of the static class description member.
void FIMDecaygx2qqxDipoleKernel::Init() {
static ClassDocumentation<FIMDecaygx2qqxDipoleKernel> documentation
("FIMDecaygx2qqxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIMDecaygx2qqxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_FIMDecaygx2qqxDipoleKernel_H
#define HERWIG_FIMDecaygx2qqxDipoleKernel_H
//
// This is the declaration of the FIMDecaygx2qqxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Stephen Webster
*
* \brief FIMDecaygx2qqxDipoleKernel implements the g -> qq
* splitting off a final-initial decay dipole
*
*/
class FIMDecaygx2qqxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIMDecaygx2qqxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FIMDecaygx2qqxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIMDecaygx2qqxDipoleKernel> initFIMDecaygx2qqxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIMDecaygx2qqxDipoleKernel & operator=(const FIMDecaygx2qqxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIMDecaygx2qqxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FIMDecaygx2qqxDipoleKernel,1> {
/** Typedef of the first base class of FIMDecaygx2qqxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIMDecaygx2qqxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIMDecaygx2qqxDipoleKernel>
: public ClassTraitsBase<Herwig::FIMDecaygx2qqxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIMDecaygx2qqxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FIMDecaygx2qqxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FIMDecaygx2qqxDipoleKernel 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_FIMDecaygx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.cc
@@ -1,187 +1,185 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FIMDecayqx2qgxDipoleKernel class.
//
#include "FIMDecayqx2qgxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FIMDecayqx2qgxDipoleKernel::FIMDecayqx2qgxDipoleKernel() : DipoleSplittingKernel() {}
-FIMDecayqx2qgxDipoleKernel::~FIMDecayqx2qgxDipoleKernel() {}
-
IBPtr FIMDecayqx2qgxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FIMDecayqx2qgxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FIMDecayqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.incomingDecaySpectator() && !ind.incomingDecayEmitter() &&
abs(ind.emitterData()->id()) < 7 &&
// This line matches to the kernel declared in a .in file for the given emitter flavour
abs(ind.emitterData()->id()) == abs(flavour()->id()) &&
!(ind.spectatorData()->mass() == ZERO) &&
// Initial state here refers to the entire event
!ind.initialStateEmitter() && !ind.initialStateSpectator();
}
bool FIMDecayqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emission(b)->id() == ParticleID::g &&
abs(sk.emitter(b)->id()) < 7 &&
abs(sk.emitter(b)->mass()) == abs(emitter(a)->mass()) &&
abs(sk.spectator(b)->mass()) == abs(spectator(a)->mass());
}
tcPDPtr FIMDecayqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
assert(flavour());
assert(abs(flavour()->id()) < 7);
return ind.emitterData()->id() > 0 ?
(tcPDPtr) flavour() : (tcPDPtr) flavour()->CC();
}
tcPDPtr FIMDecayqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FIMDecayqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FIMDecayqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
// Sudakov parameterisation variables,
// needed to calculate y.
double z = split.lastZ();
Energy pt = split.lastPt();
// Construct mass squared variables
// Note for q->qg can use the emitterMass
// (i.e. mass of emitter before splitting = mass of emitter after)
Energy2 Qijk = sqr(split.scale());
Energy2 mi2 = sqr(split.emitterMass());
Energy2 mk2 = sqr(split.recoilMass());
Energy2 sbar = Qijk - mi2 - mk2;
// Note this should be the same as Qijk
Energy2 ma2 = sqr(split.spectatorMass());
// Calculate y
double y = (sqr(pt) + sqr(1.-z)*mi2) / sbar / z / (1.-z);
if( sqr(2.*mk2+sbar*(1.-y)) - 4.*mk2*Qijk < ZERO ){
generator()->logWarning( Exception()
<< "error in FIMDecayqx2qgxDipoleKernel::evaluate -- " <<
"mk2 " << mk2/GeV2 << " mi2 " << mi2/GeV2 << " y " << y << Exception::warning );
return 0.0;
}
// zi, used in dipole splitting kernel
double zi = split.lastSplittingParameters()[0];
double vijk = sqrt( sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk ) / sbar / (1.-y);
double vtilde = sqrt( sqr(Qijk) + sqr(mi2) + sqr(mk2)
- 2.*(mi2*Qijk + mk2*Qijk + mi2*mk2) ) / sbar;
ret *=
(!strictLargeN() ? 4./3. : 3./2.)
* ( ( 2.*( 2.*mi2/sbar + 2.*y + 1. ) / ((1.+y) - zi*(1.-y))
- (vtilde/vijk) * ( (1.+zi) + 2.*mi2/y/sbar ) )
+ y/(1. - zi*(1.-y)) * ( 2.*(2.*mi2/sbar + 2.*y + 1. ) / ((1.+y) - zi*(1.-y))
- (vtilde/vijk) * ( 2. + 2.*ma2/((1. - zi*(1.-y))*sbar) ) ) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FIMDecayqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
// No dependence on the spin density matrix,
// dependence on off-diagonal terms cancels.
return {{ {0, 1.} }};
}
DecayMEPtr FIMDecayqx2qgxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
// Need variables for the AP kernels
double z = dInfo.lastSplittingParameters()[0];
Energy pt = dInfo.lastPt();
Energy mi = dInfo.emitterMass();
// Altarelli-Parisi spin-indexed kernels:
Energy den = sqrt(sqr(mi)*sqr(1.-z) + sqr(pt));
double v_AP_ppp = pt / den / sqrt(1.-z);
double v_AP_ppm = - z * v_AP_ppp ;
double v_AP_pmp = mi*(1.-z)*sqrt(1.-z) / den ;
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -1 or -1/2, 1=+1/2, 2 = +1
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = v_AP_mpm;
(*kernelPhiDep)(1,0,2) = v_AP_pmp;
(*kernelPhiDep)(0,1,2) = 0.;
(*kernelPhiDep)(1,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIMDecayqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void FIMDecayqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FIMDecayqx2qgxDipoleKernel> FIMDecayqx2qgxDipoleKernel::initFIMDecayqx2qgxDipoleKernel;
// Definition of the static class description member.
void FIMDecayqx2qgxDipoleKernel::Init() {
static ClassDocumentation<FIMDecayqx2qgxDipoleKernel> documentation
("FIMDecayqx2qgxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIMDecayqx2qgxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_FIMDecayqx2qgxDipoleKernel_H
#define HERWIG_FIMDecayqx2qgxDipoleKernel_H
//
// This is the declaration of the FIMDecayqx2qgxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Stephen Webster
*
* \brief FIMDecayqx2qgxDipoleKernel implements the q -> qg
* splitting off a final-initial decay dipole and includes the
* contribution from the splitting of the intial / decay particle
*
*/
class FIMDecayqx2qgxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIMDecayqx2qgxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FIMDecayqx2qgxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex& ind) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex& ind) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo& split) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIMDecayqx2qgxDipoleKernel> initFIMDecayqx2qgxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIMDecayqx2qgxDipoleKernel & operator=(const FIMDecayqx2qgxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIMDecayqx2qgxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FIMDecayqx2qgxDipoleKernel,1> {
/** Typedef of the first base class of FIMDecayqx2qgxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIMDecayqx2qgxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIMDecayqx2qgxDipoleKernel>
: public ClassTraitsBase<Herwig::FIMDecayqx2qgxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIMDecayqx2qgxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FIMDecayqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FIMDecayqx2qgxDipoleKernel 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_FIMDecayqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.cc
@@ -1,180 +1,178 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FIMgx2qqxDipoleKernel class.
//
#include "FIMgx2qqxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FIMgx2qqxDipoleKernel::FIMgx2qqxDipoleKernel()
: DipoleSplittingKernel() {}
-FIMgx2qqxDipoleKernel::~FIMgx2qqxDipoleKernel() {}
-
IBPtr FIMgx2qqxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FIMgx2qqxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FIMgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() == ZERO &&
flavour()->mass() != ZERO &&
!ind.initialStateEmitter() && ind.initialStateSpectator();
}
bool FIMgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emitter(b)->id() + sk.emission(b)->id() == 0 &&
abs(sk.emitter(b)->id()) < 6 &&
emitter(a)->mass() == sk.emitter(b)->mass() &&
a.spectatorPDF() == b.spectatorPDF();
}
tcPDPtr FIMgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() != ZERO);
return flavour();
}
tcPDPtr FIMgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() != ZERO);
return flavour()->CC();
}
tcPDPtr FIMgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
// TODO
// assure split.scale() is sqrt(sbar)
double FIMgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
// mi=m=mQ, Mi=0, mj=Mj=0
Energy2 mQ2 = sqr(split.emitterData()->mass());
double z = split.lastZ();
double x = 1./ ( 1. +
( sqr(split.lastPt()) + mQ2 ) /
( z*(1.-z) * sqr(split.scale()) ) );
double muQ2 = x * mQ2/sqr(split.scale());
double zm = .5 * ( 1. - sqrt( 1. - 4.*muQ2/(1.-x) ) );
double zp = .5 * ( 1. + sqrt( 1. - 4.*muQ2/(1.-x) ) );
ret *= .25 * (1.-2.*(zp-z)*(z-zm));
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FIMgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
Energy2 mi2 = sqr(dInfo.emitterData()->mass());
// Altarelli-Parisi spin-indexed kernels:
double ratio = mi2 / ( mi2 + sqr(pt) );
double root = sqrt(1.-ratio);
double v_AP_ppp = sqrt(ratio);
double v_AP_ppm = z*root;
double v_AP_pmp = -(1.-z)*root;
//double v_AP_mmm = v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) + 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp) )/max ) );
distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
return distPhiDep;
}
DecayMEPtr FIMgx2qqxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
Energy2 mi2 = sqr(dInfo.emitterData()->mass());
// Altarelli-Parisi spin-indexed kernels:
double ratio = mi2 / ( mi2 + sqr(pt) );
double root = sqrt(1.-ratio);
double v_AP_ppp = sqrt(ratio);
double v_AP_ppm = z*root;
double v_AP_pmp = -(1.-z)*root;
double v_AP_mmm = v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm;
(*kernelPhiDep)(2,1,1) = v_AP_ppp;
(*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
(*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
(*kernelPhiDep)(0,1,1) = 0.;
(*kernelPhiDep)(2,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIMgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void FIMgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FIMgx2qqxDipoleKernel> FIMgx2qqxDipoleKernel::initFIMgx2qqxDipoleKernel;
// Definition of the static class description member.
void FIMgx2qqxDipoleKernel::Init() {
static ClassDocumentation<FIMgx2qqxDipoleKernel> documentation
("FIMgx2qqxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIMgx2qqxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_FIMgx2qqxDipoleKernel_H
#define HERWIG_FIMgx2qqxDipoleKernel_H
//
// This is the declaration of the FIMgx2qqxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll
*
* \brief FIMgx2qqxDipoleKernel implements the g -> qqbar
* splitting off a final-initial dipole
*
*/
class FIMgx2qqxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIMgx2qqxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FIMgx2qqxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIMgx2qqxDipoleKernel> initFIMgx2qqxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIMgx2qqxDipoleKernel & operator=(const FIMgx2qqxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIMgx2qqxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FIMgx2qqxDipoleKernel,1> {
/** Typedef of the first base class of FIMgx2qqxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIMgx2qqxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIMgx2qqxDipoleKernel>
: public ClassTraitsBase<Herwig::FIMgx2qqxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIMgx2qqxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FIMgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FIMgx2qqxDipoleKernel 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_FIMgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.cc
@@ -1,155 +1,153 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FIMqx2qgxDipoleKernel class.
//
#include "FIMqx2qgxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FIMqx2qgxDipoleKernel::FIMqx2qgxDipoleKernel()
: DipoleSplittingKernel() {}
-FIMqx2qgxDipoleKernel::~FIMqx2qgxDipoleKernel() {}
-
IBPtr FIMqx2qgxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FIMqx2qgxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FIMqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
abs(ind.emitterData()->id()) < 7 &&
abs(ind.emitterData()->id())==abs(flavour()->id()) &&
ind.emitterData()->mass() != ZERO &&
ind.spectatorData()->mass() == ZERO &&
!ind.initialStateEmitter() && ind.initialStateSpectator();
}
bool FIMqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emission(b)->id() == ParticleID::g &&
abs(sk.emitter(b)->id()) < 7 &&
sk.emitter(b)->mass() == emitter(a)->mass() &&
a.spectatorPDF() == b.spectatorPDF();
}
tcPDPtr FIMqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
assert(flavour());
assert(abs(flavour()->id())<7 && flavour()->mass() != ZERO);
return ind.emitterData()->id() > 0 ?
(tcPDPtr) flavour() : (tcPDPtr) flavour()->CC();
}
tcPDPtr FIMqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FIMqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
// TODO
// split.scale() should be sqrt(sbar) = sqrt( Mi2 - Q2 ) !!!
double FIMqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
// Mi=mi=mQ, m=0, Mj=mj=0
Energy2 mQ2 = sqr(split.emitterMass());
double z = split.lastZ();
double x = 1. / ( 1. +
( sqr(split.lastPt()) + sqr(1.-z)*mQ2 ) /
( z*(1.-z) * sqr(split.scale()) ) );
// Simon has extra terms
ret *= (!strictLargeN() ? 4./3. : 3./2.) *
( 2./(1.-z+(1.-x)) -(1.+z) - mQ2/sqr(split.scale()) * 2.*x/(1.-x) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FIMqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
// No dependence on the spin density matrix,
// dependence on off-diagonal terms cancels.
return {{ {0, 1.} }};
}
DecayMEPtr FIMqx2qgxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
Energy mi = dInfo.emitterMass();
// Altarelli-Parisi spin-indexed kernels:
Energy den = sqrt(sqr(mi)*sqr(1.-z) + sqr(pt));
double v_AP_ppp = pt / den / sqrt(1.-z);
double v_AP_ppm = - z * v_AP_ppp ;
double v_AP_pmp = mi*(1.-z)*sqrt(1.-z) / den ;
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -1 or -1/2, 1=+1/2, 2 = +1
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = v_AP_mpm;
(*kernelPhiDep)(1,0,2) = v_AP_pmp;
(*kernelPhiDep)(0,1,2) = 0.;
(*kernelPhiDep)(1,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIMqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void FIMqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FIMqx2qgxDipoleKernel> FIMqx2qgxDipoleKernel::initFIMqx2qgxDipoleKernel;
// Definition of the static class description member.
void FIMqx2qgxDipoleKernel::Init() {
static ClassDocumentation<FIMqx2qgxDipoleKernel> documentation
("FIMqx2qgxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIMqx2qgxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_FIMqx2qgxDipoleKernel_H
#define HERWIG_FIMqx2qgxDipoleKernel_H
//
// This is the declaration of the FIMqx2qgxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll
*
* \brief FIMqx2qgxDipoleKernel implements the q -> qg
* splitting off a final-initial dipole
*
*/
class FIMqx2qgxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIMqx2qgxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FIMqx2qgxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIMqx2qgxDipoleKernel> initFIMqx2qgxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIMqx2qgxDipoleKernel & operator=(const FIMqx2qgxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIMqx2qgxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FIMqx2qgxDipoleKernel,1> {
/** Typedef of the first base class of FIMqx2qgxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIMqx2qgxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIMqx2qgxDipoleKernel>
: public ClassTraitsBase<Herwig::FIMqx2qgxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIMqx2qgxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FIMqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FIMqx2qgxDipoleKernel 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_FIMqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.cc
@@ -1,172 +1,170 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FIgx2ggxDipoleKernel class.
//
#include "FIgx2ggxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FIgx2ggxDipoleKernel::FIgx2ggxDipoleKernel()
: DipoleSplittingKernel() {}
-FIgx2ggxDipoleKernel::~FIgx2ggxDipoleKernel() {}
-
IBPtr FIgx2ggxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FIgx2ggxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FIgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() == ZERO &&
!ind.initialStateEmitter() && ind.initialStateSpectator();
}
bool FIgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emitter(b)->id() == ParticleID::g &&
sk.emission(b)->id() == ParticleID::g &&
a.spectatorPDF() == b.spectatorPDF();
}
tcPDPtr FIgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FIgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FIgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FIgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double x = 1. / ( 1. + sqr(split.lastPt()/split.scale()) / (z*(1.-z)) );
double S1=1./(1.-z+(1.-x));
double S2=1./(1.-(1.-z)+(1.-x));
double NS=(-2 + z*(1.-z)+(1.-x)*(1.+x*z*(1.-z)));
if( theAsymmetryOption == 0 ){
ret *= 3.*( S1 + 0.5 * NS);
}else if ( theAsymmetryOption == 1 ){
ret *= 3.*z*( S1 +S2 + NS );
}else{
ret *= 3.*0.5*( S1 + S2 + NS );
}
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FIgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
//double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp)) - 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_pmp))/max ) );
distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
return distPhiDep;
}
DecayMEPtr FIgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_pmp = (1.-z)*sqrt( (1.-z)/z );
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
(*kernelPhiDep)(0,2,2) = 0;
(*kernelPhiDep)(2,0,0) = 0;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIgx2ggxDipoleKernel::persistentOutput(PersistentOStream & os) const {
os << theAsymmetryOption;
}
void FIgx2ggxDipoleKernel::persistentInput(PersistentIStream & is, int) {
is >> theAsymmetryOption;
}
ClassDescription<FIgx2ggxDipoleKernel> FIgx2ggxDipoleKernel::initFIgx2ggxDipoleKernel;
// Definition of the static class description member.
void FIgx2ggxDipoleKernel::Init() {
static ClassDocumentation<FIgx2ggxDipoleKernel> documentation
("FIgx2ggxDipoleKernel");
static Parameter<FIgx2ggxDipoleKernel,int> interfacetheAsymmetryOption
("AsymmetryOption",
"The asymmetry option for final state gluon spliitings.",
&FIgx2ggxDipoleKernel::theAsymmetryOption, 1, 0, 0,
false, false, Interface::lowerlim);
}
diff --git a/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIgx2ggxDipoleKernel.h
@@ -1,197 +1,189 @@
// -*- C++ -*-
#ifndef HERWIG_FIgx2ggxDipoleKernel_H
#define HERWIG_FIgx2ggxDipoleKernel_H
//
// This is the declaration of the FIgx2ggxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief FIgx2ggxDipoleKernel implements the g -> gg
* splitting off a final-initial dipole
*
*/
class FIgx2ggxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIgx2ggxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FIgx2ggxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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:
/**
* Asymmetry option for final state gluon splittings.
*/
int theAsymmetryOption=1;
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIgx2ggxDipoleKernel> initFIgx2ggxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIgx2ggxDipoleKernel & operator=(const FIgx2ggxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIgx2ggxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FIgx2ggxDipoleKernel,1> {
/** Typedef of the first base class of FIgx2ggxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIgx2ggxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIgx2ggxDipoleKernel>
: public ClassTraitsBase<Herwig::FIgx2ggxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIgx2ggxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FIgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FIgx2ggxDipoleKernel 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_FIgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.cc
@@ -1,155 +1,153 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FIgx2qqxDipoleKernel class.
//
#include "FIgx2qqxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FIgx2qqxDipoleKernel::FIgx2qqxDipoleKernel()
: DipoleSplittingKernel() {}
-FIgx2qqxDipoleKernel::~FIgx2qqxDipoleKernel() {}
-
IBPtr FIgx2qqxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FIgx2qqxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FIgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() == ZERO &&
flavour()->mass() == ZERO &&
!ind.initialStateEmitter() && ind.initialStateSpectator();
}
bool FIgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emitter(b)->id() + sk.emission(b)->id() == 0 &&
abs(sk.emitter(b)->id()) < 6 &&
// sk.emitter(b)->mass() == ZERO &&
a.spectatorPDF() == b.spectatorPDF();
}
tcPDPtr FIgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
return flavour();
}
tcPDPtr FIgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
return flavour()->CC();
}
tcPDPtr FIgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FIgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
ret *= .25 * (1.-2.*z*(1.-z));
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FIgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppm = z;
double v_AP_pmp = -(1.-z);
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppm) + sqr(v_AP_pmp)) + 2.*abs(rho(0,2))*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*( sqr(v_AP_ppm) + sqr(v_AP_pmp) )/max ) );
distPhiDep.push_back( make_pair(-2, rho(0,2)*(v_AP_mpm*v_AP_ppm + v_AP_mmp*v_AP_pmp)/max ) );
distPhiDep.push_back( make_pair(2, rho(2,0)*(v_AP_ppm*v_AP_mpm + v_AP_pmp*v_AP_mmp)/max) );
return distPhiDep;
}
DecayMEPtr FIgx2qqxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppm = z;
double v_AP_pmp = -(1.-z);
double v_AP_mmp = -v_AP_ppm;
double v_AP_mpm = -v_AP_pmp;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1Half,PDT::Spin1Half)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = 0.;
(*kernelPhiDep)(2,1,1) = 0.;
(*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
(*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
(*kernelPhiDep)(0,1,1) = 0.;
(*kernelPhiDep)(2,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void FIgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FIgx2qqxDipoleKernel> FIgx2qqxDipoleKernel::initFIgx2qqxDipoleKernel;
// Definition of the static class description member.
void FIgx2qqxDipoleKernel::Init() {
static ClassDocumentation<FIgx2qqxDipoleKernel> documentation
("FIgx2qqxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIgx2qqxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_FIgx2qqxDipoleKernel_H
#define HERWIG_FIgx2qqxDipoleKernel_H
//
// This is the declaration of the FIgx2qqxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief FIgx2qqxDipoleKernel implements the g -> qqbar
* splitting off a final-initial dipole
*
*/
class FIgx2qqxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIgx2qqxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FIgx2qqxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIgx2qqxDipoleKernel> initFIgx2qqxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIgx2qqxDipoleKernel & operator=(const FIgx2qqxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIgx2qqxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FIgx2qqxDipoleKernel,1> {
/** Typedef of the first base class of FIgx2qqxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIgx2qqxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIgx2qqxDipoleKernel>
: public ClassTraitsBase<Herwig::FIgx2qqxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIgx2qqxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FIgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FIgx2qqxDipoleKernel 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_FIgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.cc
@@ -1,138 +1,136 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the FIqx2qgxDipoleKernel class.
//
#include "FIqx2qgxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
FIqx2qgxDipoleKernel::FIqx2qgxDipoleKernel()
: DipoleSplittingKernel() {}
-FIqx2qgxDipoleKernel::~FIqx2qgxDipoleKernel() {}
-
IBPtr FIqx2qgxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr FIqx2qgxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool FIqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
abs(ind.emitterData()->id()) < 6 &&
ind.emitterData()->mass() == ZERO &&
ind.spectatorData()->mass() == ZERO &&
!ind.initialStateEmitter() && ind.initialStateSpectator();
}
bool FIqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emission(b)->id() == ParticleID::g &&
abs(sk.emitter(b)->id()) < 6 &&
sk.emitter(b)->mass() == ZERO &&
a.spectatorPDF() == b.spectatorPDF();
}
tcPDPtr FIqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
return ind.emitterData();
}
tcPDPtr FIqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr FIqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double FIqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double x = 1. / ( 1. + sqr(split.lastPt()/split.scale()) / (z*(1.-z)) );
ret *= (!strictLargeN() ? 4./3. : 3./2.) * ( 2./(1.-z+(1.-x)) -(1.+z) + (1.-x)*(1.+3.*x*z) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
FIqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
// No dependence on the spin density matrix,
// dependence on off-diagonal terms cancels.
return {{ {0, 1.} }};
}
DecayMEPtr FIqx2qgxDipoleKernel::matrixElement( const DipoleSplittingInfo& dInfo ) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = sqrt( 1./(1.-z) );
double v_AP_ppm = -z/sqrt(1.-z);
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -1 or -1/2, 1=+1/2, 2 = +1
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = 0.;
(*kernelPhiDep)(1,0,2) = 0.;
(*kernelPhiDep)(0,1,2) = 0.;
(*kernelPhiDep)(1,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void FIqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FIqx2qgxDipoleKernel> FIqx2qgxDipoleKernel::initFIqx2qgxDipoleKernel;
// Definition of the static class description member.
void FIqx2qgxDipoleKernel::Init() {
static ClassDocumentation<FIqx2qgxDipoleKernel> documentation
("FIqx2qgxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/FIqx2qgxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_FIqx2qgxDipoleKernel_H
#define HERWIG_FIqx2qgxDipoleKernel_H
//
// This is the declaration of the FIqx2qgxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief FIqx2qgxDipoleKernel implements the q -> qg
* splitting off a final-initial dipole
*
*/
class FIqx2qgxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIqx2qgxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~FIqx2qgxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIqx2qgxDipoleKernel> initFIqx2qgxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIqx2qgxDipoleKernel & operator=(const FIqx2qgxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIqx2qgxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::FIqx2qgxDipoleKernel,1> {
/** Typedef of the first base class of FIqx2qgxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIqx2qgxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIqx2qgxDipoleKernel>
: public ClassTraitsBase<Herwig::FIqx2qgxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIqx2qgxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* FIqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class FIqx2qgxDipoleKernel 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_FIqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.cc
@@ -1,165 +1,163 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IFMgx2ggxDipoleKernel class.
//
#include "IFMgx2ggxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IFMgx2ggxDipoleKernel::IFMgx2ggxDipoleKernel()
: DipoleSplittingKernel() {}
-IFMgx2ggxDipoleKernel::~IFMgx2ggxDipoleKernel() {}
-
IBPtr IFMgx2ggxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IFMgx2ggxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IFMgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() != ZERO &&
ind.initialStateEmitter() && !ind.initialStateSpectator();
}
bool IFMgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emitter(b)->id() == ParticleID::g &&
sk.emission(b)->id() == ParticleID::g &&
a.emitterPDF() == b.emitterPDF() &&
sk.spectator(b)->mass() == spectator(a)->mass();
}
tcPDPtr IFMgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IFMgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IFMgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IFMgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
Energy pt = split.lastPt();
double ratio = sqr(pt/split.scale());
double muk2 = sqr(split.spectatorMass()/split.scale());
// Calculate x and u
double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio);
double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho));
double u = x*ratio / (1.-z);
// NOTE - The definition of muk used in the kinematics differs from that in CS
double muk2CS = x*muk2;
ret *= 3. * ( 1./(1.-x+u) - 1. + x*(1.-x) + (1.-x)/x - muk2CS*u/(x*(1.-u)) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IFMgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
double v_AP_mmm = -v_AP_ppp;
//double v_AP_mmp = -v_AP_ppm;
double v_AP_pmp = -v_AP_mpm;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm)) - 2.*abs(rho(0,2))*(v_AP_ppp*v_AP_pmp + v_AP_mmm*v_AP_mpm);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm))/max ) );
distPhiDep.push_back( make_pair(2, rho(0,2)*(v_AP_mmm*v_AP_mpm + v_AP_pmp*v_AP_ppp)/max ) );
distPhiDep.push_back( make_pair(-2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm)/max) );
return distPhiDep;
}
DecayMEPtr IFMgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_pmp = -v_AP_mpm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1, PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
(*kernelPhiDep)(0,2,2) = 0;
(*kernelPhiDep)(2,0,0) = 0;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFMgx2ggxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IFMgx2ggxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IFMgx2ggxDipoleKernel> IFMgx2ggxDipoleKernel::initIFMgx2ggxDipoleKernel;
// Definition of the static class description member.
void IFMgx2ggxDipoleKernel::Init() {
static ClassDocumentation<IFMgx2ggxDipoleKernel> documentation
("IFMgx2ggxDipoleKernelv");
}
diff --git a/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFMgx2ggxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IFMgx2ggxDipoleKernel_H
#define HERWIG_IFMgx2ggxDipoleKernel_H
//
// This is the declaration of the IFMgx2ggxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll
*
* \brief IFMgx2ggxDipoleKernel implements the g -> gg
* splitting off an initial-final dipole
*
*/
class IFMgx2ggxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFMgx2ggxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IFMgx2ggxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFMgx2ggxDipoleKernel> initIFMgx2ggxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFMgx2ggxDipoleKernel & operator=(const IFMgx2ggxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFMgx2ggxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IFMgx2ggxDipoleKernel,1> {
/** Typedef of the first base class of IFMgx2ggxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFMgx2ggxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFMgx2ggxDipoleKernel>
: public ClassTraitsBase<Herwig::IFMgx2ggxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFMgx2ggxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IFMgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IFMgx2ggxDipoleKernel 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_IFMgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.cc
@@ -1,168 +1,166 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IFMgx2qqxDipoleKernel class.
//
#include "IFMgx2qqxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IFMgx2qqxDipoleKernel::IFMgx2qqxDipoleKernel()
: DipoleSplittingKernel() {}
-IFMgx2qqxDipoleKernel::~IFMgx2qqxDipoleKernel() {}
-
IBPtr IFMgx2qqxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IFMgx2qqxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IFMgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() != ZERO &&
flavour()->mass() == ZERO &&
ind.initialStateEmitter() && !ind.initialStateSpectator();
}
bool IFMgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
flavour() == sk.flavour() &&
abs(flavour()->id()) < 6 &&
flavour()->mass() == ZERO &&
spectator(a)->mass() == sk.spectator(b)->mass() &&
a.emitterPDF() == b.emitterPDF();
}
tcPDPtr IFMgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
return flavour();
}
tcPDPtr IFMgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
return flavour();
}
tcPDPtr IFMgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IFMgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
Energy pt = split.lastPt();
double ratio = sqr(pt/split.scale());
double muk2 = sqr(split.spectatorMass()/split.scale());
// Calculate x and u
double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio);
double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho));
double u = x*ratio / (1.-z);
// NOTE - The definition of muk used in the kinematics differs from that in CS
double muk2CS = x*muk2;
ret *= 0.5 * (!strictLargeN() ? 4./3. : 3./2.) *
( x + 2.*(1.-x)/x - 2.*muk2CS/x*u/(1.-u) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IFMgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = sqrt(1./z);
double v_AP_mpm = (1.-z)/sqrt(z);
double v_AP_mmm = -v_AP_ppp;
double v_AP_pmp = -v_AP_mpm;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = sqr(v_AP_ppp) + sqr(v_AP_mpm)
- 2.*abs(rho(0,2))*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm);
distPhiDep.push_back(make_pair( 0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_mpm))/max ) );
distPhiDep.push_back(make_pair( 2, rho(0,2)*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm )/max ) );
distPhiDep.push_back(make_pair( -2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm )/max ) );
return distPhiDep;
}
DecayMEPtr IFMgx2qqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = sqrt(1./z);
double v_AP_mpm = (1.-z)/sqrt(z);
double v_AP_mmm = -v_AP_ppp;
double v_AP_pmp = -v_AP_mpm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1, PDT::Spin1Half)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -1 or -1/2, 1=+1/2, 2 = +1
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(1,2,1) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,1) = 0.;
(*kernelPhiDep)(1,2,0) = 0.;
(*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
(*kernelPhiDep)(1,0,1) = v_AP_pmp*phase;
(*kernelPhiDep)(0,2,1) = 0.;
(*kernelPhiDep)(1,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFMgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IFMgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IFMgx2qqxDipoleKernel> IFMgx2qqxDipoleKernel::initIFMgx2qqxDipoleKernel;
// Definition of the static class description member.
void IFMgx2qqxDipoleKernel::Init() {
static ClassDocumentation<IFMgx2qqxDipoleKernel> documentation
("IFMgx2qqxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFMgx2qqxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IFMgx2qqxDipoleKernel_H
#define HERWIG_IFMgx2qqxDipoleKernel_H
//
// This is the declaration of the IFgx2qqxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll
*
* \brief IFMgx2qqxDipoleKernel implements the g -> qq
* splitting off an initial-final dipole
*
*/
class IFMgx2qqxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFMgx2qqxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IFMgx2qqxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFMgx2qqxDipoleKernel> initIFMgx2qqxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFMgx2qqxDipoleKernel & operator=(const IFMgx2qqxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFMgx2qqxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IFMgx2qqxDipoleKernel,1> {
/** Typedef of the first base class of IFMgx2qqxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFMgx2qqxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFMgx2qqxDipoleKernel>
: public ClassTraitsBase<Herwig::IFMgx2qqxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFMgx2qqxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IFMgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IFMgx2qqxDipoleKernel 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_IFMgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.cc b/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.cc
@@ -1,144 +1,142 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IFMqx2gqxDipoleKernel class.
//
#include "IFMqx2gqxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IFMqx2gqxDipoleKernel::IFMqx2gqxDipoleKernel()
: DipoleSplittingKernel() {}
-IFMqx2gqxDipoleKernel::~IFMqx2gqxDipoleKernel() {}
-
IBPtr IFMqx2gqxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IFMqx2gqxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IFMqx2gqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
abs(ind.emitterData()->id()) < 6 &&
ind.emitterData()->mass() == ZERO &&
ind.spectatorData()->mass() != ZERO &&
ind.initialStateEmitter() && !ind.initialStateSpectator();
}
bool IFMqx2gqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
a.emitterData() == b.emitterData() &&
emitter(a) == sk.emitter(b) &&
spectator(a)->mass() == sk.spectator(b)->mass() &&
a.emitterPDF() == b.emitterPDF();
}
tcPDPtr IFMqx2gqxDipoleKernel::emitter(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IFMqx2gqxDipoleKernel::emission(const DipoleIndex& ind) const {
return ind.emitterData()->CC();
}
tcPDPtr IFMqx2gqxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IFMqx2gqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
Energy pt = split.lastPt();
double ratio = sqr(pt/split.scale());
double muk2 = sqr(split.spectatorMass()/split.scale());
// Calculate x
double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio);
double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho));
ret *= .5 * ( 1.-2.*x*(1.-x) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IFMqx2gqxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
// No dependence on the spin density matrix,
// dependence on off-diagonal terms cancels.
return {{ {0, 1.} }};
}
DecayMEPtr IFMqx2gqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppm = z;
double v_AP_mpm = (1.-z);
double v_AP_mmp = -v_AP_ppm;
double v_AP_pmp = -v_AP_mpm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1Half, PDT::Spin1Half)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = 0.;
(*kernelPhiDep)(2,1,1) = 0.;
(*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
(*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
(*kernelPhiDep)(0,1,1) = 0.;
(*kernelPhiDep)(2,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFMqx2gqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IFMqx2gqxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IFMqx2gqxDipoleKernel> IFMqx2gqxDipoleKernel::initIFMqx2gqxDipoleKernel;
// Definition of the static class description member.
void IFMqx2gqxDipoleKernel::Init() {
static ClassDocumentation<IFMqx2gqxDipoleKernel> documentation
("IFMqx2gqxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.h b/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFMqx2gqxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IFMqx2gqxDipoleKernel_H
#define HERWIG_IFMqx2gqxDipoleKernel_H
//
// This is the declaration of the IFqx2gqxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll
*
* \brief IFMqx2gqxDipoleKernel implements the q -> gqbar
* splitting off an initial-final dipole
*
*/
class IFMqx2gqxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFMqx2gqxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IFMqx2gqxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFMqx2gqxDipoleKernel> initIFMqx2gqxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFMqx2gqxDipoleKernel & operator=(const IFMqx2gqxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFMqx2gqxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IFMqx2gqxDipoleKernel,1> {
/** Typedef of the first base class of IFMqx2gqxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFMqx2gqxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFMqx2gqxDipoleKernel>
: public ClassTraitsBase<Herwig::IFMqx2gqxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFMqx2gqxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IFMqx2gqxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IFMqx2gqxDipoleKernel 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_IFMqx2gqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.cc
@@ -1,147 +1,145 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IFMqx2qgxDipoleKernel class.
//
#include "IFMqx2qgxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IFMqx2qgxDipoleKernel::IFMqx2qgxDipoleKernel()
: DipoleSplittingKernel() {}
-IFMqx2qgxDipoleKernel::~IFMqx2qgxDipoleKernel() {}
-
IBPtr IFMqx2qgxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IFMqx2qgxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IFMqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
abs(ind.emitterData()->id()) < 6 &&
ind.emitterData()->mass() == ZERO &&
ind.spectatorData()->mass() != ZERO &&
ind.initialStateEmitter() && !ind.initialStateSpectator();
}
bool IFMqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
emitter(a) == sk.emitter(b) &&
emission(a) == sk.emission(b) &&
spectator(a)->mass() == sk.spectator(b)->mass() &&
a.emitterPDF() == b.emitterPDF();
}
tcPDPtr IFMqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
return ind.emitterData();
}
tcPDPtr IFMqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IFMqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IFMqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
Energy pt = split.lastPt();
double ratio = sqr(pt/split.scale());
double muk2 = sqr(split.spectatorMass()/split.scale());
// Calculate x and u
double rho = 1. - 4.*ratio*(1.-muk2)*z*(1.-z)/sqr(1.-z+ratio);
double x = 0.5*((1.-z+ratio)/(ratio*(1.-muk2))) * (1. - sqrt(rho));
double u = x*ratio / (1.-z);
// 19/01/2017 - SW: Removed finite term as its effect on
// the ratio of -ve/+ve kernels is small
ret *= (!strictLargeN() ? 4./3. : 3./2.) * ( 2./(1.-x+u) - (1.+x) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IFMqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
// No dependence on the spin density matrix,
// dependence on off-diagonal terms cancels.
return {{ {0, 1.} }};
}
DecayMEPtr IFMqx2qgxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = sqrt( 1./(1.-z) );
double v_AP_ppm = -z/sqrt(1.-z);
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1Half, PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = 0.;
(*kernelPhiDep)(1,0,2) = 0.;
(*kernelPhiDep)(0,1,2) = 0.;
(*kernelPhiDep)(1,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFMqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IFMqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IFMqx2qgxDipoleKernel> IFMqx2qgxDipoleKernel::initIFMqx2qgxDipoleKernel;
// Definition of the static class description member.
void IFMqx2qgxDipoleKernel::Init() {
static ClassDocumentation<IFMqx2qgxDipoleKernel> documentation
("IFMqx2qgxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFMqx2qgxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IFMqx2qgxDipoleKernel_H
#define HERWIG_IFMqx2qgxDipoleKernel_H
//
// This is the declaration of the IFqx2qgxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll
*
* \brief IFMqx2qgxDipoleKernel implements the q -> qg
* splitting off an initial-final dipole
*
*/
class IFMqx2qgxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFMqx2qgxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IFMqx2qgxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFMqx2qgxDipoleKernel> initIFMqx2qgxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFMqx2qgxDipoleKernel & operator=(const IFMqx2qgxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFMqx2qgxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IFMqx2qgxDipoleKernel,1> {
/** Typedef of the first base class of IFMqx2qgxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFMqx2qgxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFMqx2qgxDipoleKernel>
: public ClassTraitsBase<Herwig::IFMqx2qgxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFMqx2qgxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IFMqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IFMqx2qgxDipoleKernel 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_IFMqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.cc
@@ -1,158 +1,156 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IFgx2ggxDipoleKernel class.
//
#include "IFgx2ggxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IFgx2ggxDipoleKernel::IFgx2ggxDipoleKernel()
: DipoleSplittingKernel() {}
-IFgx2ggxDipoleKernel::~IFgx2ggxDipoleKernel() {}
-
IBPtr IFgx2ggxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IFgx2ggxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IFgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() == ZERO &&
ind.initialStateEmitter() && !ind.initialStateSpectator();
}
bool IFgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emitter(b)->id() == ParticleID::g &&
sk.emission(b)->id() == ParticleID::g &&
a.emitterPDF() == b.emitterPDF();
}
tcPDPtr IFgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IFgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IFgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IFgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double ratio = sqr(split.lastPt()/split.scale());
double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
double u = 0.5*((1.-z+ratio)/(1.-z))*(1.-sqrt(rho));
ret *= 3. * ( 1./(1.-x+u) + (1.-x)/x - 1. + x*(1.-x) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IFgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
double v_AP_mmm = -v_AP_ppp;
//double v_AP_mmp = -v_AP_ppm;
double v_AP_pmp = -v_AP_mpm;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm)) - 2.*abs(rho(0,2))*(v_AP_ppp*v_AP_pmp + v_AP_mmm*v_AP_mpm);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm))/max ) );
distPhiDep.push_back( make_pair(2, rho(0,2)*(v_AP_mmm*v_AP_mpm + v_AP_pmp*v_AP_ppp)/max ) );
distPhiDep.push_back( make_pair(-2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm)/max) );
return distPhiDep;
}
DecayMEPtr IFgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_pmp = -v_AP_mpm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1, PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
(*kernelPhiDep)(0,2,2) = 0;
(*kernelPhiDep)(2,0,0) = 0;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFgx2ggxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IFgx2ggxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IFgx2ggxDipoleKernel> IFgx2ggxDipoleKernel::initIFgx2ggxDipoleKernel;
// Definition of the static class description member.
void IFgx2ggxDipoleKernel::Init() {
static ClassDocumentation<IFgx2ggxDipoleKernel> documentation
("IFgx2ggxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFgx2ggxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IFgx2ggxDipoleKernel_H
#define HERWIG_IFgx2ggxDipoleKernel_H
//
// This is the declaration of the IFgx2ggxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IFgx2ggxDipoleKernel implements the g -> gg
* splitting off an initial-final dipole
*
*/
class IFgx2ggxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFgx2ggxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IFgx2ggxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFgx2ggxDipoleKernel> initIFgx2ggxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFgx2ggxDipoleKernel & operator=(const IFgx2ggxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFgx2ggxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IFgx2ggxDipoleKernel,1> {
/** Typedef of the first base class of IFgx2ggxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFgx2ggxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFgx2ggxDipoleKernel>
: public ClassTraitsBase<Herwig::IFgx2ggxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFgx2ggxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IFgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IFgx2ggxDipoleKernel 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_IFgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.cc
@@ -1,160 +1,158 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IFgx2qqxDipoleKernel class.
//
#include "IFgx2qqxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IFgx2qqxDipoleKernel::IFgx2qqxDipoleKernel()
: DipoleSplittingKernel() {}
-IFgx2qqxDipoleKernel::~IFgx2qqxDipoleKernel() {}
-
IBPtr IFgx2qqxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IFgx2qqxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IFgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() == ZERO &&
flavour()->mass() == ZERO &&
ind.initialStateEmitter() && !ind.initialStateSpectator();
}
bool IFgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
flavour() == sk.flavour() &&
abs(flavour()->id()) < 6 &&
flavour()->mass() == ZERO &&
a.emitterPDF() == b.emitterPDF();
}
tcPDPtr IFgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
return flavour();
}
tcPDPtr IFgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
return flavour();
}
tcPDPtr IFgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IFgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double ratio = sqr(split.lastPt()/split.scale());
double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
ret *= 0.5 * (!strictLargeN() ? 4./3. : 3./2.) * ( x + 2.*(1.-x)/x );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IFgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = sqrt(1./z);
double v_AP_mpm = (1.-z)/sqrt(z);
double v_AP_mmm = -v_AP_ppp;
double v_AP_pmp = -v_AP_mpm;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = sqr(v_AP_ppp) + sqr(v_AP_mpm)
- 2.*abs(rho(0,2))*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm);
distPhiDep.push_back(make_pair( 0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_mpm))/max ) );
distPhiDep.push_back(make_pair( 2, rho(0,2)*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm )/max ) );
distPhiDep.push_back(make_pair( -2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm )/max ) );
return distPhiDep;
}
DecayMEPtr IFgx2qqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = sqrt(1./z);
double v_AP_mpm = (1.-z)/sqrt(z);
double v_AP_mmm = -v_AP_ppp;
double v_AP_pmp = -v_AP_mpm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1, PDT::Spin1Half)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -1 or -1/2, 1=+1/2, 2 = +1
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(1,2,1) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,1) = 0.;
(*kernelPhiDep)(1,2,0) = 0.;
(*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
(*kernelPhiDep)(1,0,1) = v_AP_pmp*phase;
(*kernelPhiDep)(0,2,1) = 0.;
(*kernelPhiDep)(1,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IFgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IFgx2qqxDipoleKernel> IFgx2qqxDipoleKernel::initIFgx2qqxDipoleKernel;
// Definition of the static class description member.
void IFgx2qqxDipoleKernel::Init() {
static ClassDocumentation<IFgx2qqxDipoleKernel> documentation
("IFgx2qqxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFgx2qqxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IFgx2qqxDipoleKernel_H
#define HERWIG_IFgx2qqxDipoleKernel_H
//
// This is the declaration of the IFgx2qqxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IFgx2qqxDipoleKernel implements the g -> qq
* splitting off an initial-final dipole
*
*/
class IFgx2qqxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFgx2qqxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IFgx2qqxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFgx2qqxDipoleKernel> initIFgx2qqxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFgx2qqxDipoleKernel & operator=(const IFgx2qqxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFgx2qqxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IFgx2qqxDipoleKernel,1> {
/** Typedef of the first base class of IFgx2qqxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFgx2qqxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFgx2qqxDipoleKernel>
: public ClassTraitsBase<Herwig::IFgx2qqxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFgx2qqxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IFgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IFgx2qqxDipoleKernel 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_IFgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.cc b/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.cc
@@ -1,139 +1,137 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IFqx2gqxDipoleKernel class.
//
#include "IFqx2gqxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IFqx2gqxDipoleKernel::IFqx2gqxDipoleKernel()
: DipoleSplittingKernel() {}
-IFqx2gqxDipoleKernel::~IFqx2gqxDipoleKernel() {}
-
IBPtr IFqx2gqxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IFqx2gqxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IFqx2gqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
abs(ind.emitterData()->id()) < 6 &&
ind.emitterData()->mass() == ZERO &&
ind.spectatorData()->mass() == ZERO &&
ind.initialStateEmitter() && !ind.initialStateSpectator();
}
bool IFqx2gqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
a.emitterData() == b.emitterData() &&
emitter(a) == sk.emitter(b) &&
a.emitterPDF() == b.emitterPDF();
}
tcPDPtr IFqx2gqxDipoleKernel::emitter(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IFqx2gqxDipoleKernel::emission(const DipoleIndex& ind) const {
return ind.emitterData()->CC();
}
tcPDPtr IFqx2gqxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IFqx2gqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double ratio = sqr(split.lastPt()/split.scale());
double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
ret *= .5 * ( 1.-2.*x*(1.-x) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IFqx2gqxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
// No dependence on the spin density matrix,
// dependence on off-diagonal terms cancels.
return {{ {0, 1.} }};
}
DecayMEPtr IFqx2gqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppm = z;
double v_AP_mpm = (1.-z);
double v_AP_mmp = -v_AP_ppm;
double v_AP_pmp = -v_AP_mpm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1Half, PDT::Spin1Half)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = 0.;
(*kernelPhiDep)(2,1,1) = 0.;
(*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
(*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
(*kernelPhiDep)(0,1,1) = 0.;
(*kernelPhiDep)(2,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFqx2gqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IFqx2gqxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IFqx2gqxDipoleKernel> IFqx2gqxDipoleKernel::initIFqx2gqxDipoleKernel;
// Definition of the static class description member.
void IFqx2gqxDipoleKernel::Init() {
static ClassDocumentation<IFqx2gqxDipoleKernel> documentation
("IFqx2gqxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.h b/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFqx2gqxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IFqx2gqxDipoleKernel_H
#define HERWIG_IFqx2gqxDipoleKernel_H
//
// This is the declaration of the IFqx2gqxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IFqx2gqxDipoleKernel implements the q -> gqbar
* splitting off an initial-final dipole
*
*/
class IFqx2gqxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFqx2gqxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IFqx2gqxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFqx2gqxDipoleKernel> initIFqx2gqxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFqx2gqxDipoleKernel & operator=(const IFqx2gqxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFqx2gqxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IFqx2gqxDipoleKernel,1> {
/** Typedef of the first base class of IFqx2gqxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFqx2gqxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFqx2gqxDipoleKernel>
: public ClassTraitsBase<Herwig::IFqx2gqxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFqx2gqxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IFqx2gqxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IFqx2gqxDipoleKernel 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_IFqx2gqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.cc
@@ -1,140 +1,138 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IFqx2qgxDipoleKernel class.
//
#include "IFqx2qgxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IFqx2qgxDipoleKernel::IFqx2qgxDipoleKernel()
: DipoleSplittingKernel() {}
-IFqx2qgxDipoleKernel::~IFqx2qgxDipoleKernel() {}
-
IBPtr IFqx2qgxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IFqx2qgxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IFqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
abs(ind.emitterData()->id()) < 6 &&
ind.emitterData()->mass() == ZERO &&
ind.spectatorData()->mass() == ZERO &&
ind.initialStateEmitter() && !ind.initialStateSpectator();
}
bool IFqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
emitter(a) == sk.emitter(b) &&
emission(a) == sk.emission(b) &&
a.emitterPDF() == b.emitterPDF();
}
tcPDPtr IFqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
return ind.emitterData();
}
tcPDPtr IFqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IFqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IFqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double ratio = sqr(split.lastPt()/split.scale());
double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
double u = 0.5*((1.-z+ratio)/(1.-z))*(1.-sqrt(rho));
ret *= (!strictLargeN() ? 4./3. : 3./2.) * ( 2./(1.-x+u) - (1.+x) + u*(1.+3.*x*(1.-u) ) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IFqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
// No dependence on the spin density matrix,
// dependence on off-diagonal terms cancels.
return {{ {0, 1.} }};
}
DecayMEPtr IFqx2qgxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = sqrt( 1./(1.-z) );
double v_AP_ppm = -z/sqrt(1.-z);
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1Half, PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = 0.;
(*kernelPhiDep)(1,0,2) = 0.;
(*kernelPhiDep)(0,1,2) = 0.;
(*kernelPhiDep)(1,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IFqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IFqx2qgxDipoleKernel> IFqx2qgxDipoleKernel::initIFqx2qgxDipoleKernel;
// Definition of the static class description member.
void IFqx2qgxDipoleKernel::Init() {
static ClassDocumentation<IFqx2qgxDipoleKernel> documentation
("IFqx2qgxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IFqx2qgxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IFqx2qgxDipoleKernel_H
#define HERWIG_IFqx2qgxDipoleKernel_H
//
// This is the declaration of the IFqx2qgxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IFqx2qgxDipoleKernel implements the q -> qg
* splitting off an initial-final dipole
*
*/
class IFqx2qgxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFqx2qgxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IFqx2qgxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFqx2qgxDipoleKernel> initIFqx2qgxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFqx2qgxDipoleKernel & operator=(const IFqx2qgxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFqx2qgxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IFqx2qgxDipoleKernel,1> {
/** Typedef of the first base class of IFqx2qgxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFqx2qgxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFqx2qgxDipoleKernel>
: public ClassTraitsBase<Herwig::IFqx2qgxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFqx2qgxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IFqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IFqx2qgxDipoleKernel 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_IFqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.cc b/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.cc
@@ -1,160 +1,158 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IIgx2ggxDipoleKernel class.
//
#include "IIgx2ggxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IIgx2ggxDipoleKernel::IIgx2ggxDipoleKernel()
: DipoleSplittingKernel() {}
-IIgx2ggxDipoleKernel::~IIgx2ggxDipoleKernel() {}
-
IBPtr IIgx2ggxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IIgx2ggxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IIgx2ggxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() == ZERO &&
ind.initialStateEmitter() && ind.initialStateSpectator();
}
bool IIgx2ggxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
sk.emitter(b)->id() == ParticleID::g &&
sk.emission(b)->id() == ParticleID::g &&
a.emitterPDF() == b.emitterPDF() &&
a.spectatorData() == b.spectatorData() &&
a.spectatorPDF() == b.spectatorPDF();
}
tcPDPtr IIgx2ggxDipoleKernel::emitter(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IIgx2ggxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IIgx2ggxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IIgx2ggxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double ratio = sqr(split.lastPt()/split.scale());
double x = z*(1.-z)/(1.-z+ratio);
ret *= 3. * ( x/(1.-x) + (1.-x)/x +x*(1.-x) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IIgx2ggxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
double v_AP_mmm = -v_AP_ppp;
//double v_AP_mmp = -v_AP_ppm;
double v_AP_pmp = -v_AP_mpm;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = (sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm))
- 2.*abs(rho(0,2))*(v_AP_ppp*v_AP_pmp + v_AP_mmm*v_AP_mpm);
distPhiDep.push_back( make_pair(0, (rho(0,0)+rho(2,2))*
(sqr(v_AP_ppp) + sqr(v_AP_ppm) + sqr(v_AP_mpm))/max ) );
distPhiDep.push_back( make_pair(2, rho(0,2)*(v_AP_mmm*v_AP_mpm + v_AP_pmp*v_AP_ppp)/max ) );
distPhiDep.push_back( make_pair(-2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm)/max) );
return distPhiDep;
}
DecayMEPtr IIgx2ggxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = -sqrt( 1./(z*(1.-z)) );
double v_AP_ppm = z*sqrt( z / (1.-z) );
double v_AP_mpm = -(1.-z)*sqrt( (1.-z)/z );
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
double v_AP_pmp = -v_AP_mpm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1, PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(2,2,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(2,2,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,2) = v_AP_pmp*phase;
(*kernelPhiDep)(0,2,2) = 0;
(*kernelPhiDep)(2,0,0) = 0;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IIgx2ggxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IIgx2ggxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IIgx2ggxDipoleKernel> IIgx2ggxDipoleKernel::initIIgx2ggxDipoleKernel;
// Definition of the static class description member.
void IIgx2ggxDipoleKernel::Init() {
static ClassDocumentation<IIgx2ggxDipoleKernel> documentation
("IIgx2ggxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.h b/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IIgx2ggxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IIgx2ggxDipoleKernel_H
#define HERWIG_IIgx2ggxDipoleKernel_H
//
// This is the declaration of the IIgx2ggxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IIgx2ggxDipoleKernel implements the g -> gg
* splitting off an initial-initial dipole
*
*/
class IIgx2ggxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IIgx2ggxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IIgx2ggxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IIgx2ggxDipoleKernel> initIIgx2ggxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IIgx2ggxDipoleKernel & operator=(const IIgx2ggxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IIgx2ggxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IIgx2ggxDipoleKernel,1> {
/** Typedef of the first base class of IIgx2ggxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IIgx2ggxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IIgx2ggxDipoleKernel>
: public ClassTraitsBase<Herwig::IIgx2ggxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IIgx2ggxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IIgx2ggxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IIgx2ggxDipoleKernel 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_IIgx2ggxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.cc b/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.cc
@@ -1,161 +1,159 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IIgx2qqxDipoleKernel class.
//
#include "IIgx2qqxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IIgx2qqxDipoleKernel::IIgx2qqxDipoleKernel()
: DipoleSplittingKernel() {}
-IIgx2qqxDipoleKernel::~IIgx2qqxDipoleKernel() {}
-
IBPtr IIgx2qqxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IIgx2qqxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IIgx2qqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
ind.emitterData()->id() == ParticleID::g &&
ind.spectatorData()->mass() == ZERO &&
flavour()->mass() == ZERO &&
ind.initialStateEmitter() && ind.initialStateSpectator();
}
bool IIgx2qqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
flavour() == sk.flavour() &&
abs(flavour()->id()) < 6 &&
flavour()->mass() == ZERO &&
a.emitterPDF() == b.emitterPDF() &&
a.spectatorData() == b.spectatorData() &&
a.spectatorPDF() == b.spectatorPDF();
}
tcPDPtr IIgx2qqxDipoleKernel::emitter(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
return flavour();
}
tcPDPtr IIgx2qqxDipoleKernel::emission(const DipoleIndex&) const {
assert(flavour());
assert(abs(flavour()->id()) < 6 && flavour()->mass() == ZERO);
return flavour();
}
tcPDPtr IIgx2qqxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IIgx2qqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double ratio = sqr(split.lastPt()/split.scale());
double x = z*(1.-z)/(1.-z+ratio);
ret *= 0.5 * (!strictLargeN() ? 4./3. : 3./2.) * ( 1./x +sqr(1.-x)/x );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IIgx2qqxDipoleKernel::generatePhi(const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = sqrt(1./z);
double v_AP_mpm = (1.-z)/sqrt(z);
double v_AP_mmm = -v_AP_ppp;
double v_AP_pmp = -v_AP_mpm;
// Initialise variables for the distributions
vector< pair<int, Complex> > distPhiDep;
double max = sqr(v_AP_ppp) + sqr(v_AP_mpm)
- 2.*abs(rho(0,2))*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm);
distPhiDep.push_back(make_pair( 0, (rho(0,0)+rho(2,2))*(sqr(v_AP_ppp) + sqr(v_AP_mpm))/max ) );
distPhiDep.push_back(make_pair( 2, rho(0,2)*(v_AP_pmp*v_AP_ppp + v_AP_mmm*v_AP_mpm )/max ) );
distPhiDep.push_back(make_pair( -2, rho(2,0)*(v_AP_ppp*v_AP_pmp + v_AP_mpm*v_AP_mmm )/max ) );
return distPhiDep;
}
DecayMEPtr IIgx2qqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = sqrt(1./z);
double v_AP_mpm = (1.-z)/sqrt(z);
double v_AP_mmm = -v_AP_ppp;
double v_AP_pmp = -v_AP_mpm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1, PDT::Spin1Half)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -1 or -1/2, 1=+1/2, 2 = +1
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(1,2,1) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,1) = 0.;
(*kernelPhiDep)(1,2,0) = 0.;
(*kernelPhiDep)(0,2,0) = v_AP_mpm/phase;
(*kernelPhiDep)(1,0,1) = v_AP_pmp*phase;
(*kernelPhiDep)(0,2,1) = 0.;
(*kernelPhiDep)(1,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IIgx2qqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IIgx2qqxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IIgx2qqxDipoleKernel> IIgx2qqxDipoleKernel::initIIgx2qqxDipoleKernel;
// Definition of the static class description member.
void IIgx2qqxDipoleKernel::Init() {
static ClassDocumentation<IIgx2qqxDipoleKernel> documentation
("IIgx2qqxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.h b/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IIgx2qqxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IIgx2qqxDipoleKernel_H
#define HERWIG_IIgx2qqxDipoleKernel_H
//
// This is the declaration of the IIgx2qqxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IIgx2qqxDipoleKernel implements the g -> qq
* splitting off an initial-initial dipole
*
*/
class IIgx2qqxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IIgx2qqxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IIgx2qqxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IIgx2qqxDipoleKernel> initIIgx2qqxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IIgx2qqxDipoleKernel & operator=(const IIgx2qqxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IIgx2qqxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IIgx2qqxDipoleKernel,1> {
/** Typedef of the first base class of IIgx2qqxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IIgx2qqxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IIgx2qqxDipoleKernel>
: public ClassTraitsBase<Herwig::IIgx2qqxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IIgx2qqxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IIgx2qqxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IIgx2qqxDipoleKernel 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_IIgx2qqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.cc b/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.cc
@@ -1,140 +1,138 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IIqx2gqxDipoleKernel class.
//
#include "IIqx2gqxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IIqx2gqxDipoleKernel::IIqx2gqxDipoleKernel()
: DipoleSplittingKernel() {}
-IIqx2gqxDipoleKernel::~IIqx2gqxDipoleKernel() {}
-
IBPtr IIqx2gqxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IIqx2gqxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IIqx2gqxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
abs(ind.emitterData()->id()) < 6 &&
ind.emitterData()->mass() == ZERO &&
ind.spectatorData()->mass() == ZERO &&
ind.initialStateEmitter() && ind.initialStateSpectator();
}
bool IIqx2gqxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
a.emitterData() == b.emitterData() &&
emitter(a) == sk.emitter(b) &&
a.emitterPDF() == b.emitterPDF() &&
a.spectatorData() == b.spectatorData() &&
a.spectatorPDF() == b.spectatorPDF();
}
tcPDPtr IIqx2gqxDipoleKernel::emitter(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IIqx2gqxDipoleKernel::emission(const DipoleIndex& ind) const {
return ind.emitterData()->CC();
}
tcPDPtr IIqx2gqxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IIqx2gqxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double ratio = sqr(split.lastPt()/split.scale());
double x = z*(1.-z)/(1.-z+ratio);
ret *= .5 * ( 1.-2.*x*(1.-x) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IIqx2gqxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
// No dependence on the spin density matrix,
// dependence on off-diagonal terms cancels.
return {{ {0, 1.} }};
}
DecayMEPtr IIqx2gqxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppm = z;
double v_AP_mpm = (1.-z);
double v_AP_mmp = -v_AP_ppm;
double v_AP_pmp = -v_AP_mpm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1, PDT::Spin1Half, PDT::Spin1Half)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = 0.;
(*kernelPhiDep)(2,1,1) = 0.;
(*kernelPhiDep)(0,0,1) = v_AP_mmp/phase;
(*kernelPhiDep)(2,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = v_AP_mpm/phase;
(*kernelPhiDep)(2,0,1) = v_AP_pmp*phase;
(*kernelPhiDep)(0,1,1) = 0.;
(*kernelPhiDep)(2,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IIqx2gqxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IIqx2gqxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IIqx2gqxDipoleKernel> IIqx2gqxDipoleKernel::initIIqx2gqxDipoleKernel;
// Definition of the static class description member.
void IIqx2gqxDipoleKernel::Init() {
static ClassDocumentation<IIqx2gqxDipoleKernel> documentation
("IIqx2gqxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.h b/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IIqx2gqxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IIqx2gqxDipoleKernel_H
#define HERWIG_IIqx2gqxDipoleKernel_H
//
// This is the declaration of the IIqx2gqxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IIqx2gqxDipoleKernel implements the q -> gqbar
* splitting off an initial-initial dipole
*
*/
class IIqx2gqxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IIqx2gqxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IIqx2gqxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IIqx2gqxDipoleKernel> initIIqx2gqxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IIqx2gqxDipoleKernel & operator=(const IIqx2gqxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IIqx2gqxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IIqx2gqxDipoleKernel,1> {
/** Typedef of the first base class of IIqx2gqxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IIqx2gqxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IIqx2gqxDipoleKernel>
: public ClassTraitsBase<Herwig::IIqx2gqxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IIqx2gqxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IIqx2gqxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IIqx2gqxDipoleKernel 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_IIqx2gqxDipoleKernel_H */
diff --git a/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.cc b/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.cc
--- a/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.cc
+++ b/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.cc
@@ -1,139 +1,137 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the IIqx2qgxDipoleKernel class.
//
#include "IIqx2qgxDipoleKernel.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
IIqx2qgxDipoleKernel::IIqx2qgxDipoleKernel()
: DipoleSplittingKernel() {}
-IIqx2qgxDipoleKernel::~IIqx2qgxDipoleKernel() {}
-
IBPtr IIqx2qgxDipoleKernel::clone() const {
return new_ptr(*this);
}
IBPtr IIqx2qgxDipoleKernel::fullclone() const {
return new_ptr(*this);
}
bool IIqx2qgxDipoleKernel::canHandle(const DipoleIndex& ind) const {
return
useThisKernel() &&
abs(ind.emitterData()->id()) < 6 &&
ind.emitterData()->mass() == ZERO &&
ind.spectatorData()->mass() == ZERO &&
ind.initialStateEmitter() && ind.initialStateSpectator();
}
bool IIqx2qgxDipoleKernel::canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const {
assert(canHandle(a));
if ( !canHandle(b) )
return false;
return
emitter(a) == sk.emitter(b) &&
emission(a) == sk.emission(b) &&
a.emitterPDF() == b.emitterPDF() &&
a.spectatorData() == b.spectatorData() &&
a.spectatorPDF() == b.spectatorPDF();
}
tcPDPtr IIqx2qgxDipoleKernel::emitter(const DipoleIndex& ind) const {
return ind.emitterData();
}
tcPDPtr IIqx2qgxDipoleKernel::emission(const DipoleIndex&) const {
return getParticleData(ParticleID::g);
}
tcPDPtr IIqx2qgxDipoleKernel::spectator(const DipoleIndex& ind) const {
return ind.spectatorData();
}
double IIqx2qgxDipoleKernel::evaluate(const DipoleSplittingInfo& split) const {
double ret = alphaPDF(split);
double z = split.lastZ();
double ratio = sqr(split.lastPt()/split.scale());
double x = z*(1.-z)/(1.-z+ratio);
ret *= (!strictLargeN() ? 4./3. : 3./2.) * ( (1.+sqr(x))/(1.-x) );
return ret > 0. ? ret : 0.;
}
vector< pair<int, Complex> >
IIqx2qgxDipoleKernel::generatePhi(const DipoleSplittingInfo&, const RhoDMatrix&) const {
// No dependence on the spin density matrix,
// dependence on off-diagonal terms cancels.
return {{ {0, 1.} }};
}
DecayMEPtr IIqx2qgxDipoleKernel::matrixElement(const DipoleSplittingInfo& dInfo) const {
double z = dInfo.lastZ();
// Altarelli-Parisi spin-indexed kernels:
double v_AP_ppp = sqrt( 1./(1.-z) );
double v_AP_ppm = -z/sqrt(1.-z);
double v_AP_mmm = -v_AP_ppp;
double v_AP_mmp = -v_AP_ppm;
// Construct the (phi-dependent) spin-unaveraged splitting kernel
DecayMEPtr kernelPhiDep
(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half, PDT::Spin1Half, PDT::Spin1)));
Complex phase = exp(Complex(0.,1.)*dInfo.lastPhi());
// 0 = -, 2 = +
(*kernelPhiDep)(0,0,0) = v_AP_mmm*phase;
(*kernelPhiDep)(1,1,2) = v_AP_ppp/phase;
(*kernelPhiDep)(0,0,2) = v_AP_mmp/phase;
(*kernelPhiDep)(1,1,0) = v_AP_ppm*phase;
(*kernelPhiDep)(0,1,0) = 0.;
(*kernelPhiDep)(1,0,2) = 0.;
(*kernelPhiDep)(0,1,2) = 0.;
(*kernelPhiDep)(1,0,0) = 0.;
return kernelPhiDep;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IIqx2qgxDipoleKernel::persistentOutput(PersistentOStream & ) const {
}
void IIqx2qgxDipoleKernel::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IIqx2qgxDipoleKernel> IIqx2qgxDipoleKernel::initIIqx2qgxDipoleKernel;
// Definition of the static class description member.
void IIqx2qgxDipoleKernel::Init() {
static ClassDocumentation<IIqx2qgxDipoleKernel> documentation
("IIqx2qgxDipoleKernel");
}
diff --git a/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.h b/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.h
--- a/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.h
+++ b/Shower/Dipole/Kernels/IIqx2qgxDipoleKernel.h
@@ -1,192 +1,184 @@
// -*- C++ -*-
#ifndef HERWIG_IIqx2qgxDipoleKernel_H
#define HERWIG_IIqx2qgxDipoleKernel_H
//
// This is the declaration of the IIqx2qgxDipoleKernel class.
//
#include "DipoleSplittingKernel.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IIqx2qgxDipoleKernel implements the q -> qg
* splitting off an initial-initial dipole
*
*/
class IIqx2qgxDipoleKernel: public DipoleSplittingKernel {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IIqx2qgxDipoleKernel();
- /**
- * The destructor.
- */
- virtual ~IIqx2qgxDipoleKernel();
- //@}
-
public:
/**
* Return true, if this splitting kernel
* applies to the given dipole index.
*/
virtual bool canHandle(const DipoleIndex&) const;
/**
* Return true, if this splitting kernel is
* the same for the given index a, as the given
* splitting kernel for index b.
*/
virtual bool canHandleEquivalent(const DipoleIndex& a,
const DipoleSplittingKernel& sk,
const DipoleIndex& b) const;
/**
* Return the emitter data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emitter(const DipoleIndex&) const;
/**
* Return the emission data after splitting, given
* a dipole index.
*/
virtual tcPDPtr emission(const DipoleIndex&) const;
/**
* Return the spectator data after splitting, given
* a dipole index.
*/
virtual tcPDPtr spectator(const DipoleIndex&) const;
/**
* Evaluate this splitting kernel for the given
* dipole splitting.
*/
virtual double evaluate(const DipoleSplittingInfo&) const;
/**
* Evaluate rho_ii' V_ijk V*_i'jk / equivalent for initial-state splitting,
* required for generating spin-correlated azimuthal angles.
**/
virtual vector< pair<int, Complex> > generatePhi( const DipoleSplittingInfo& dInfo, const RhoDMatrix& rho) const;
/**
* Return the completely spin-unaveraged (i.e. spin-indexed) splitting kernel.
**/
virtual DecayMEPtr matrixElement(const DipoleSplittingInfo& dInfo) 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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IIqx2qgxDipoleKernel> initIIqx2qgxDipoleKernel;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IIqx2qgxDipoleKernel & operator=(const IIqx2qgxDipoleKernel &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IIqx2qgxDipoleKernel. */
template <>
struct BaseClassTrait<Herwig::IIqx2qgxDipoleKernel,1> {
/** Typedef of the first base class of IIqx2qgxDipoleKernel. */
typedef Herwig::DipoleSplittingKernel NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IIqx2qgxDipoleKernel class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IIqx2qgxDipoleKernel>
: public ClassTraitsBase<Herwig::IIqx2qgxDipoleKernel> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IIqx2qgxDipoleKernel"; }
/**
* The name of a file containing the dynamic library where the class
* IIqx2qgxDipoleKernel is implemented. It may also include several, space-separated,
* libraries if the class IIqx2qgxDipoleKernel 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_IIqx2qgxDipoleKernel_H */
diff --git a/Shower/Dipole/Kinematics/DipoleSplittingKinematics.cc b/Shower/Dipole/Kinematics/DipoleSplittingKinematics.cc
--- a/Shower/Dipole/Kinematics/DipoleSplittingKinematics.cc
+++ b/Shower/Dipole/Kinematics/DipoleSplittingKinematics.cc
@@ -1,389 +1,387 @@
// -*- C++ -*-
//
// DipoleSplittingKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the DipoleSplittingKinematics class.
//
#include "DipoleSplittingKinematics.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/MatrixElement/Matchbox/Phasespace/RandomHelpers.h"
#include <limits>
using namespace Herwig;
DipoleSplittingKinematics::DipoleSplittingKinematics()
: HandlerBase(), theIRCutoff(1.0*GeV),
theXMin(1.e-5), theJacobian(0.0),
theLastPt(0.0*GeV), theLastZ(0.0), theLastPhi(0.0),
theLastEmitterZ(1.0), theLastSpectatorZ(1.0),
theLastSplittingParameters(),theOpenZBoundaries(1) {}
-DipoleSplittingKinematics::~DipoleSplittingKinematics() {}
-
void DipoleSplittingKinematics::persistentOutput(PersistentOStream & os) const {
os << ounit(theIRCutoff,GeV) << theXMin << theMCCheck<<theOpenZBoundaries;
}
void DipoleSplittingKinematics::persistentInput(PersistentIStream & is, int) {
is >> iunit(theIRCutoff,GeV) >> theXMin >> theMCCheck>>theOpenZBoundaries;
}
void DipoleSplittingKinematics::prepareSplitting(DipoleSplittingInfo& dInfo) {
dInfo.splittingKinematics(this);
if ( lastPt() > IRCutoff() )
dInfo.lastPt(lastPt());
else {
dInfo.lastPt(0.0*GeV);
dInfo.didStopEvolving();
}
dInfo.lastZ(lastZ());
dInfo.lastPhi(lastPhi());
dInfo.lastEmitterZ(lastEmitterZ());
dInfo.lastSpectatorZ(lastSpectatorZ());
dInfo.splittingParameters().resize(lastSplittingParameters().size());
copy(lastSplittingParameters().begin(),lastSplittingParameters().end(),
dInfo.splittingParameters().begin());
}
Energy DipoleSplittingKinematics::ptMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const {
return ptMax(dScale, emX, specX, dInfo.index(), split);
}
Energy DipoleSplittingKinematics::ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
tPPtr, tPPtr) const {
return ptMax(dScale, emX, specX, dIndex, split);
}
Energy DipoleSplittingKinematics::QMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const {
return QMax(dScale, emX, specX, dInfo.index(), split);
}
Energy DipoleSplittingKinematics::QMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
tPPtr, tPPtr) const {
return QMax(dScale, emX, specX, dIndex, split);
}
Energy DipoleSplittingKinematics::generatePt(double r, Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
double& weight) const {
Energy maxPt = ptMax(dScale,emX,specX,dIndex,split);
if ( maxPt <= IRCutoff() ) {
weight = 0.0;
return ZERO;
}
weight *= log(sqr(maxPt/IRCutoff()));
return IRCutoff()*pow(maxPt/IRCutoff(),r);
}
double DipoleSplittingKinematics::ptToRandom(Energy pt, Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split) const {
Energy maxPt = ptMax(dScale,emX,specX,dIndex,split);
assert(pt >= IRCutoff() && pt <= maxPt);
return log(pt/IRCutoff())/log(maxPt/IRCutoff());
}
double DipoleSplittingKinematics::generateZ(double r, Energy pt, int sampling,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split,
double& weight) const {
pair<double,double> zLims = zBoundaries(pt,dInfo,split);
if(zLims.first==zLims.second){
weight = 0.0;
return 0.0;
}
using namespace RandomHelpers;
if ( sampling == FlatZ ) {
pair<double,double> kw = generate(flat(zLims.first,zLims.second),r);
if ( kw.second != 0. ) {
weight *= kw.second;
return kw.first;
}
else {
assert( kw.first < zLims.first || kw.first > zLims.second );
weight *= kw.second;
return -1.;
}
}
if ( sampling == OneOverZ ) {
pair<double,double> kw = generate(inverse(0.0,zLims.first,zLims.second),r);
if ( kw.second != 0. ) {
weight *= kw.second;
return kw.first;
}
else {
assert( kw.first < zLims.first || kw.first > zLims.second );
weight *= kw.second;
return -1.;
}
}
if ( sampling == OneOverOneMinusZ ) {
pair<double,double> kw = generate(inverse(1.0,zLims.first,zLims.second),r);
if ( kw.second != 0. ) {
weight *= kw.second;
return kw.first;
}
else {
assert( kw.first < zLims.first || kw.first > zLims.second );
weight *= kw.second;
return -1.;
}
}
if ( sampling == OneOverZOneMinusZ ) {
pair<double,double> kw = generate(inverse(0.0,zLims.first,zLims.second) +
inverse(1.0,zLims.first,zLims.second),r);
if ( kw.second != 0. ) {
weight *= kw.second;
return kw.first;
}
else {
assert( kw.first < zLims.first || kw.first > zLims.second );
weight *= kw.second;
return -1.;
}
}
weight = 0.0;
return 0.0;
}
Lorentz5Momentum DipoleSplittingKinematics::getKt(const Lorentz5Momentum& p1,
const Lorentz5Momentum& p2,
Energy pt,
double phi,
bool spacelike) const {
Lorentz5Momentum P;
// CoM frame
if ( !spacelike )
P = p1 + p2;
// Breit frame
else
P = p1 - p2;
Energy mag = sqrt(abs(P.m2()));
// Define Q. The 'boost' part of this transforms from the current
// frame into a frame (') in which P' = Q
Lorentz5Momentum Q =
!spacelike ?
Lorentz5Momentum(ZERO,ZERO,ZERO,mag,mag) :
Lorentz5Momentum(ZERO,ZERO,mag,ZERO,-mag);
// This is required to make the boost parameter
// gamma positive (construct the 00 term of the
// transformtion below to see this)
//if ( spacelike && P.z() < -mag )
//Q.setZ(-Q.z());
// Below is safer than above as it avoids
// cases of very small positive (P*Q + Q2)
if ( spacelike && P.z() < ZERO )
Q.setZ(-Q.z());
Energy2 Q2 = Q.m2();
// Establish if we need to boost
bool boost =
abs((P-Q).vect().mag2()/GeV2) > 1e-10 ||
abs((P-Q).t()/GeV) > 1e-5;
// Initialise copy of p1 to transform in the following
Lorentz5Momentum inFrame1(p1);
if ( boost )
inFrame1 = inFrame1 - ((P*inFrame1+Q*inFrame1)/(Q2+P*Q))*(P+Q) + 2.*((P*inFrame1)/Q2)*Q;
// Compute components of kt
double cPhi = cos(phi);
double sPhi = sqrt(1.-sqr(cPhi));
if ( phi > Constants::pi )
sPhi = -sPhi;
// Initialise kt
Lorentz5Momentum kt;
// By 'timelike' case we mean we work in the centre-of-momentum frame
// The boost to the com frame is defined upto some rotation,
// here we do the rotation to/from the frame with boosted p1 along the +ve z-axis
if ( !spacelike ) {
Axis inFrame1Unit = inFrame1.vect().unit();
if ( inFrame1Unit.perp2() > 1e-12 ) {
// 'n' indicates normalised momenta components
double pxn = inFrame1Unit.x();
double pyn = inFrame1Unit.y();
double pzn = inFrame1Unit.z();
double den = 1./(1.+pzn);
kt.setT(ZERO);
kt.setX( pt * ( (sqr(pyn)*den + pzn)*cPhi - pxn*pyn*den*sPhi ) );
kt.setY( pt * ( -pxn*pyn*den*cPhi + (sqr(pxn)*den + pzn)*sPhi) );
kt.setZ( -pt * ( pxn*cPhi + pyn*sPhi ) );
}
// If boosted p1 already lies along the z-axis, construct the pt
// in this frame, rotating to put boosted p1 along the *+ve* z-axis
// if required
else {
// Note pzn will simply be +1 or -1 in this case
double pzn = inFrame1Unit.z();
// Multiply y component by pzn:
// In the case of pzn = -1, this corresponds to a rotation
// about the x-axis as done in boostToSplitting
kt.setT(ZERO);
kt.setX( pt * cPhi );
kt.setY( pt * pzn*sPhi );
kt.setZ(ZERO);
}
}
// By 'spacelike' we mean we work in the Breit frame.
// The transformation to the breit frame above is
// defined up to boosts in the x- and y-directions,
// here we do the boosts to put the momenta along the z-axis
else {
Energy ptx = inFrame1.x();
Energy pty = inFrame1.y();
// q/2 = energy component of inFrame1 AFTER applying
// boosts to eliminate the x and y components. Therefore
// we calculate q from the mass and the z-component as
// these will not change due to these boosts.
Energy q = 2.*sqrt(sqr(inFrame1) + sqr(inFrame1.z()));
Energy Qp = sqrt(4.*(sqr(ptx)+sqr(pty))+sqr(q));
Energy Qy = sqrt(4.*sqr(pty)+sqr(q));
// Most straightforward way to construct kt in frame
// where p1 lies along the positive z-axis
double pzn = inFrame1.z()/abs(inFrame1.z());
kt.setT(2.*pt*(ptx*q*cPhi+pty*Qp*pzn*sPhi)/(q*Qy));
kt.setX(pt*(Qp*q*cPhi+4.*ptx*pty*pzn*sPhi)/(q*Qy));
kt.setY(pt*Qy*pzn*sPhi/q);
kt.setZ(ZERO);
}
// Transform back to the lab frame
// Note Q*kt = 0
if ( boost )
kt = kt - ((P*kt+Q*kt)/(Q2+P*Q))*(P+Q);// + 2.*((Q*kt)/Q2)*P;
kt.setMass(-pt);
kt.rescaleRho();
return kt;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
AbstractClassDescription<DipoleSplittingKinematics> DipoleSplittingKinematics::initDipoleSplittingKinematics;
// Definition of the static class description member.
void DipoleSplittingKinematics::Init() {
static ClassDocumentation<DipoleSplittingKinematics> documentation
("DipoleSplittingKinematics is the base class for dipole splittings "
"as performed in the dipole shower.");
static Parameter<DipoleSplittingKinematics,Energy> interfaceIRCutoff
("IRCutoff",
"The IR cutoff to be used by this splitting kinematics.",
&DipoleSplittingKinematics::theIRCutoff, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<DipoleSplittingKinematics,double> interfaceXMin
("XMin",
"The minimum momentum fraction for incoming partons",
&DipoleSplittingKinematics::theXMin, 1.0e-5, 0.0, 1.0,
false, false, Interface::limited);
static Reference<DipoleSplittingKinematics,DipoleMCCheck> interfaceMCCheck
("MCCheck",
"[debug option] MCCheck",
&DipoleSplittingKinematics::theMCCheck, false, false, true, true, false);
interfaceMCCheck.rank(-1);
static Switch<DipoleSplittingKinematics,int> interfaceOpenZBoundaries
("OpenZBoundaries", "",
&DipoleSplittingKinematics::theOpenZBoundaries, 0, false, false);
static SwitchOption interfaceOpenZBoundarieshardScale
(interfaceOpenZBoundaries, "Hard", "", 0);
static SwitchOption interfaceOpenZBoundariesfull
(interfaceOpenZBoundaries, "Full", "", 1);
static SwitchOption interfaceOpenZBoundariesDipoleScale
(interfaceOpenZBoundaries, "DipoleScale", "", 2);
}
diff --git a/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h b/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h
--- a/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h
+++ b/Shower/Dipole/Kinematics/DipoleSplittingKinematics.h
@@ -1,672 +1,664 @@
// -*- C++ -*-
//
// DipoleSplittingKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_DipoleSplittingKinematics_H
#define HERWIG_DipoleSplittingKinematics_H
//
// This is the declaration of the DipoleSplittingKinematics class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Vectors/Lorentz5Vector.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Utilities/UtilityBase.h"
#include "Herwig/Shower/Dipole/Utility/DipoleMCCheck.h"
namespace Herwig {
using namespace ThePEG;
class DipoleIndex;
class DipoleSplittingInfo;
class DipoleSplittingKernel;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief DipoleSplittingKinematics is the base class for dipole splittings
* as performed in the dipole shower.
*
* @see \ref DipoleSplittingKinematicsInterfaces "The interfaces"
* defined for DipoleSplittingKinematics.
*/
class DipoleSplittingKinematics: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
DipoleSplittingKinematics();
- /**
- * The destructor.
- */
- virtual ~DipoleSplittingKinematics();
- //@}
-
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
virtual pair<double,double> kappaSupport(const DipoleSplittingInfo&) const {
return {0.0,1.0};
}
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
virtual pair<double,double> xiSupport(const DipoleSplittingInfo&) const {
return {0.0,1.0};
}
/**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const {
// MEMinBias produces non-zero zeros.
if(abs(pEmitter*pSpectator)<0.0000001*GeV2)return ZERO;
assert(pEmitter*pSpectator >= ZERO);
return sqrt(2.*pEmitter*pSpectator);
}
/**
* Return the mass of the system absorbing
* the recoil in the dipole splitting.
* This is overloaded in the decay dipoles.
*/
virtual Energy recoilMassKin(const Lorentz5Momentum&,
const Lorentz5Momentum& pSpectator) const {
return pSpectator.m();
}
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split) const =0;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
tPPtr emitter, tPPtr spectator) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split) const =0;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
tPPtr emitter, tPPtr spectator) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const = 0;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const = 0;
/**
* Return the infrared cutoff.
*/
virtual Energy IRCutoff() const { return theIRCutoff; }
/**
* Return the minimum momentum fraction for
* incoming partons
*/
double xMin() const { return theXMin; }
/**
* Generate a pt
*/
Energy generatePt(double r, Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
double& weight) const;
/**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy pt,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const = 0;
/**
* Enumerate the variants of sampling z
*/
enum ZSamplingOptions {
FlatZ = 0,
OneOverZ,
OneOverOneMinusZ,
OneOverZOneMinusZ
};
/**
* Generate a z value flat
*/
double generateZ(double r, Energy pt, int sampling,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split,
double& weight) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel&) = 0;
/**
* Get the splitting phasespace weight associated to
* the last call to generateSplitting. This is taken to
* be the single particle phasespace times 16 \pi^2 divided
* by the relevant propagator invariant.
*/
double jacobian() const { return theJacobian; }
/**
* Return true, if this splitting kinematics
* class is capable of delivering an overestimate
* to the jacobian.
*/
virtual bool haveOverestimate() const { return false; }
/**
* Return the overestimated jacobian for the
* last generated parameters.
*/
virtual double jacobianOverestimate() const { return -1.; }
/**
* Return the last generated pt
*/
Energy lastPt() const { return theLastPt; }
/**
* Return the last generated momentum fraction.
*/
double lastZ() const { return theLastZ; }
/**
* Return the last calculated zPrime for massive FF and decay dipoles.
*/
// Do not need in current implementation,
// using lastSplittingParameters instead.
//double lastZPrime() const { return theLastZPrime; }
/**
* Return the last generated azimuthal angle.
*/
double lastPhi() const { return theLastPhi; }
/**
* Return the momentum fraction, by which the emitter's
* momentum fraction should be divided after the splitting.
*/
double lastEmitterZ() const { return theLastEmitterZ; }
/**
* Return the momentum fraction, by which the spectator's
* momentum fraction should be divided after the splitting.
*/
double lastSpectatorZ() const { return theLastSpectatorZ; }
/**
* Return any additional parameters needed to
* evaluate the splitting kernel or to generate the
* full splitting.
*/
const vector<double>& lastSplittingParameters() const { return theLastSplittingParameters; }
/**
* Complete a DipoleSplittingInfo object with
* the parameters generated by the last call to
* generateSplitting()
*/
void prepareSplitting(DipoleSplittingInfo& dInfo);
public:
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) = 0;
/**
* Return the emitter's momentum after the splitting.
*/
const Lorentz5Momentum& lastEmitterMomentum() const { return theEmitterMomentum; }
/**
* Return the spectator's momentum after the splitting.
*/
const Lorentz5Momentum& lastSpectatorMomentum() const { return theSpectatorMomentum; }
/**
* Return the emission's momentum.
*/
const Lorentz5Momentum& lastEmissionMomentum() const { return theEmissionMomentum; }
/*
* Return true, if there is a transformation which should
* be applied to all other final state particles except the ones
* involved in the splitting after having performed the splitting.
*/
virtual bool doesTransform () const { return false; }
/**
* Calculate and store a required Lorentz transformation
**/
virtual void setTransformation () {};
/*
* Use the Dipole scale instead of hardpt for z-boundaries.
*/
int openZBoundaries() const { return theOpenZBoundaries; }
/*
* perform the transformation if required.
*/
virtual void transform (PPtr&) {};
/*
* SW 30/01/2019: Test feature only, not for release.
* Return true to only apply the transformation to non-coloured particles.
* Note this requires careful handling in DipoleEventRecord
*/
//virtual bool transformHardOnly() const { return false; }
/**
* SW 30/01/2019: Test feature only, not for release.
* In II case use colourless particles only to absorb recoil
*/
//virtual void transformHard ( PPtr& ) {};
/**
* SW 30/01/2019: Used in DipoleEventRecord to prepare for
* transformHard, test feature only, not for release.
* Add to splitRecoilMomentum for transformation
*/
// void addToRecoilMom( const Lorentz5Momentum& mom ) {
// Lorentz5Momentum newRecoilMom = splitRecoilMomentum() + mom;
// splitRecoilMomentum(newRecoilMom);
// }
/*
* Return true if this splitting is of a dipole which contains
* a decayed parton and requires the remnant to absorb the recoil.
*/
virtual bool isDecay() const { return false; }
/**
* Perform the recoil in the case of a decayed parton
*/
//virtual Lorentz5Momentum decayRecoil ( const Lorentz5Momentum& p, const int) { return p; }
/**
* Perform the recoil in the case of a decayed parton
*/
virtual void decayRecoil ( PList& ) {};
/**
* Return the pVector, required for spin correlations.
*/
virtual Lorentz5Momentum pVector(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum&,
const DipoleSplittingInfo&) const {
return pEmitter;
}
/**
* Return the nVector, required for spin correlations.
*/
virtual Lorentz5Momentum nVector(const Lorentz5Momentum&,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo&) const {
return pSpectator;
}
// {;}
protected:
/**
* Calculate a transverse momentum for the given momenta,
* invariant pt and azimuth.
*/
Lorentz5Momentum getKt(const Lorentz5Momentum& p1,
const Lorentz5Momentum& p2,
Energy pt,
double phi,
bool spacelike = false) const;
/**
* Set the splitting phasespace weight associated to
* the last call to generateSplitting. This is taken to
* be the single particle phasespace times 16 \pi^2 divided
* by the relevant propagator invariant.
*/
void jacobian(double w) { theJacobian = w; }
/**
* Set the last generated pt
*/
void lastPt(Energy p) { theLastPt = p; }
/**
* Set the last generated momentum fraction.
*/
void lastZ(double z) { theLastZ = z; }
/**
* Set the last calculated zPrime for massive FF and decay dipoles.
*/
// Do not need in current implementation,
// using lastSplittingParameters instead.
//void lastZPrime(double zPrime) { theLastZPrime = zPrime; }
/**
* Set the last generated azimuthal angle.
*/
void lastPhi(double p) { theLastPhi = p; }
/**
* Set the momentum fraction, by which the emitter's
* momentum fraction should be divided after the splitting.
*/
void lastEmitterZ(double z) { theLastEmitterZ = z; }
/**
* Set the momentum fraction, by which the spectator's
* momentum fraction should be divided after the splitting.
*/
void lastSpectatorZ(double z) { theLastSpectatorZ = z; }
/**
* Access any additional parameters needed to
* evaluate the splitting kernel or to generate the
* full splitting.
*/
vector<double>& splittingParameters() { return theLastSplittingParameters; }
/**
* Set the emitter's momentum after the splitting.
*/
void emitterMomentum(const Lorentz5Momentum& p) { theEmitterMomentum = p; }
/**
* Set the spectator's momentum after the splitting.
*/
void spectatorMomentum(const Lorentz5Momentum& p) { theSpectatorMomentum = p; }
/**
* Set the emission's momentum.
*/
void emissionMomentum(const Lorentz5Momentum& p) { theEmissionMomentum = p; }
/**
* Set the momentum of the recoil system after the splitting.
*/
void splitRecoilMomentum( const Lorentz5Momentum& mom ) { theSplitRecoilMomentum = mom; }
/**
* Return the momentum of the recoil system after splitting.
*/
const Lorentz5Momentum& splitRecoilMomentum() const { return theSplitRecoilMomentum; }
public:
/**
* 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();
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);
//@}
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The infrared cutoff associated to this
* splitting kinematics.
*/
Energy theIRCutoff;
/**
* The minimum momentum fraction for
* incoming partons
*/
double theXMin;
/**
* The last calculated splitting phase space weight.
*/
double theJacobian;
/**
* The last generated pt
*/
Energy theLastPt;
/**
* The last generated momentum fraction.
*/
double theLastZ;
/**
* The last calculated zPrime required for massive FF
* and decay kinematics dipoles.
* zPrime := qi.nk / (qi+qj).nk (qj = emission momentum)
*/
// Do not need in current implementation,
// using lastSplittingParameters instead.
//double theLastZPrime;
/**
* The last generated azimuthal angle.
*/
double theLastPhi;
/**
* The momentum fraction, by which the emitter's
* momentum fraction should be divided after the splitting.
*/
double theLastEmitterZ;
/**
* The momentum fraction, by which the spectator's
* momentum fraction should be divided after the splitting.
*/
double theLastSpectatorZ;
/**
* Any additional parameters needed to
* evaluate the splitting kernel or to generate the
* full splitting.
*/
vector<double> theLastSplittingParameters;
/**
* The emitter's momentum after the splitting.
*/
Lorentz5Momentum theEmitterMomentum;
/**
* The emission's momentum after the splitting.
*/
Lorentz5Momentum theEmissionMomentum;
/**
* The spectator's momentum after the splitting.
*/
Lorentz5Momentum theSpectatorMomentum;
/**
* The momentum of the recoil system after the splitting,
* used in decay dipole kinematics.
*/
Lorentz5Momentum theSplitRecoilMomentum;
int theOpenZBoundaries;
protected:
/**
* Pointer to a check histogram object
*/
Ptr<DipoleMCCheck>::ptr theMCCheck;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is an abstract class.
*/
static AbstractClassDescription<DipoleSplittingKinematics> initDipoleSplittingKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DipoleSplittingKinematics & operator=(const DipoleSplittingKinematics &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of DipoleSplittingKinematics. */
template <>
struct BaseClassTrait<Herwig::DipoleSplittingKinematics,1> {
/** Typedef of the first base class of DipoleSplittingKinematics. */
typedef HandlerBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the DipoleSplittingKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::DipoleSplittingKinematics>
: public ClassTraitsBase<Herwig::DipoleSplittingKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::DipoleSplittingKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* DipoleSplittingKinematics is implemented. It may also include several, space-separated,
* libraries if the class DipoleSplittingKinematics 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_DipoleSplittingKinematics_H */
diff --git a/Shower/Dipole/Kinematics/FFLightKinematics.cc b/Shower/Dipole/Kinematics/FFLightKinematics.cc
--- a/Shower/Dipole/Kinematics/FFLightKinematics.cc
+++ b/Shower/Dipole/Kinematics/FFLightKinematics.cc
@@ -1,175 +1,173 @@
// -*- C++ -*-
//
// FFLightKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FFLightKinematics class.
//
#include "FFLightKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
using namespace Herwig;
FFLightKinematics::FFLightKinematics()
: DipoleSplittingKinematics() {}
-FFLightKinematics::~FFLightKinematics() {}
-
IBPtr FFLightKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FFLightKinematics::fullclone() const {
return new_ptr(*this);
}
Energy FFLightKinematics::ptMax(Energy dScale,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return dScale/2.;
}
Energy FFLightKinematics::QMax(Energy dScale,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return dScale;
}
Energy FFLightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale*sqrt(z*(1.-z));
}
Energy FFLightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale/sqrt(z*(1.-z));
}
pair<double,double> FFLightKinematics::zBoundaries(Energy pt,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel&) const {
Energy hard=dInfo.hardPt();
if(openZBoundaries()>0)hard=dInfo.scale()/2.;
const double s = sqrt(1.-sqr(pt/hard));
return {0.5*(1.-s),0.5*(1.+s)};
}
bool FFLightKinematics::generateSplitting(double kappa, double xi, double rphi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel& split) {
double weight = 1.0;
Energy pt = generatePt(kappa,info.scale(),
info.emitterX(),info.spectatorX(),
info.index(),split,
weight);
if ( pt < IRCutoff() || pt > info.hardPt() ) {
jacobian(0.0);
return false;
}
double z = 0.0;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
z = generateZ(xi,pt,FlatZ,
info,split,weight);
} else {
z = generateZ(xi,pt,OneOverZOneMinusZ,
info,split,weight);
}
} else {
z = generateZ(xi,pt,OneOverOneMinusZ,
info,split,weight);
}
double y = sqr(pt/info.scale())/(z*(1.-z));
if ( z < 0.0 || z > 1.0 ||
y < 0.0 || y > 1.0 ) {
jacobian(0.0);
return false;
}
double phi = 2.*Constants::pi*rphi;
jacobian(weight*(1.-y));
lastPt(pt);
lastZ(z);
lastPhi(phi);
if ( theMCCheck )
theMCCheck->book(1.,1.,info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
void FFLightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
double y = sqr(pt / (pEmitter+pSpectator).m()) / (z*(1.-z));
Lorentz5Momentum kt =
getKt(pEmitter, pSpectator, pt, dInfo.lastPhi());
Lorentz5Momentum em = z*pEmitter + y*(1.-z)*pSpectator + kt;
Lorentz5Momentum emm = (1.-z)*pEmitter + z*y*pSpectator - kt;
Lorentz5Momentum spe = (1.-y)*pSpectator;
em.setMass(ZERO);
em.rescaleEnergy();
emm.setMass(ZERO);
emm.rescaleEnergy();
spe.setMass(ZERO);
spe.rescaleEnergy();
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFLightKinematics::persistentOutput(PersistentOStream & ) const {
}
void FFLightKinematics::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FFLightKinematics> FFLightKinematics::initFFLightKinematics;
// Definition of the static class description member.
void FFLightKinematics::Init() {
static ClassDocumentation<FFLightKinematics> documentation
("FFLightKinematics implements massless splittings "
"off a final-final dipole.");
}
diff --git a/Shower/Dipole/Kinematics/FFLightKinematics.h b/Shower/Dipole/Kinematics/FFLightKinematics.h
--- a/Shower/Dipole/Kinematics/FFLightKinematics.h
+++ b/Shower/Dipole/Kinematics/FFLightKinematics.h
@@ -1,200 +1,192 @@
// -*- C++ -*-
//
// FFLightKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFLightKinematics_H
#define HERWIG_FFLightKinematics_H
//
// This is the declaration of the FFLightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief FFLightKinematics implements massless splittings
* off a final-final dipole.
*
*/
class FFLightKinematics: public DipoleSplittingKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFLightKinematics();
- /**
- * The destructor.
- */
- virtual ~FFLightKinematics();
- //@}
-
public:
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel&) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel&) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy pt,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& dIndex,
const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FFLightKinematics> initFFLightKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFLightKinematics & operator=(const FFLightKinematics &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FFLightKinematics. */
template <>
struct BaseClassTrait<Herwig::FFLightKinematics,1> {
/** Typedef of the first base class of FFLightKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FFLightKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FFLightKinematics>
: public ClassTraitsBase<Herwig::FFLightKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FFLightKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* FFLightKinematics is implemented. It may also include several, space-separated,
* libraries if the class FFLightKinematics 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_FFLightKinematics_H */
diff --git a/Shower/Dipole/Kinematics/FFMassiveKinematics.cc b/Shower/Dipole/Kinematics/FFMassiveKinematics.cc
--- a/Shower/Dipole/Kinematics/FFMassiveKinematics.cc
+++ b/Shower/Dipole/Kinematics/FFMassiveKinematics.cc
@@ -1,436 +1,434 @@
// -*- C++ -*-
//
// FFMassiveKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FFMassiveKinematics class.
//
#include "FFMassiveKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
#include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
#include "ThePEG/Interface/Switch.h"
// TODO: remove after verification
// only for checking for NaN or inf
#include <gsl/gsl_math.h>
using namespace Herwig;
FFMassiveKinematics::FFMassiveKinematics()
: DipoleSplittingKinematics() {}
-FFMassiveKinematics::~FFMassiveKinematics() {}
-
IBPtr FFMassiveKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FFMassiveKinematics::fullclone() const {
return new_ptr(*this);
}
pair<double,double> FFMassiveKinematics::kappaSupport(const DipoleSplittingInfo&) const {
return {0.0,1.0};
}
pair<double,double> FFMassiveKinematics::xiSupport(const DipoleSplittingInfo& split) const {
double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
if ( split.index().emitterData()->id() == ParticleID::g ) {
if ( split.emissionData()->id() != ParticleID::g )
return {0.5*(1.-c),0.5*(1.+c)};
double b = log((1.+c)/(1.-c));
return {-b,b};
}
return {-log(0.5*(1.+c)),-log(0.5*(1.-c))};
}
Energy FFMassiveKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const {
return (pEmitter+pSpectator).m();
}
Energy FFMassiveKinematics::ptMax(Energy dScale,
double, double,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const {
DipoleIndex ind = dInfo.index();
double mui2 = 0.;
// g->gg and g->qqbar
if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
mui2 = sqr(split.emitter(ind)->mass() / dScale);
}
// Otherwise have X->Xg (should work for SUSY)
else {
mui2 = sqr(dInfo.emitterMass()/dScale);
}
double muj2 = sqr(split.emission(ind)->mass() / dScale);
double muk = dInfo.spectatorMass()/dScale;
return rootOfKallen(mui2, muj2, sqr(1.-muk)) / ( 2.-2.*muk ) * dScale;
}
Energy FFMassiveKinematics::ptMax(Energy dScale,
double, double,
const DipoleIndex& ind,
const DipoleSplittingKernel& split,
tPPtr emitter, tPPtr spectator) const {
double mui2 = 0.;
// g->gg and g->qqbar
if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
mui2 = sqr(split.emitter(ind)->mass() / dScale);
}
// Otherwise have X->Xg (should work for SUSY)
else {
mui2 = sqr(emitter->mass()/dScale);
}
double muj2 = sqr(split.emission(ind)->mass() / dScale);
double muk = spectator->mass()/dScale;
return rootOfKallen(mui2, muj2, sqr(1.-muk)) / ( 2.-2.*muk ) * dScale;
}
Energy FFMassiveKinematics::QMax(Energy dScale,
double, double,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel&) const {
assert(false && "implementation missing");
double Muk = dInfo.spectatorMass() / dScale;
return dScale * ( 1.-2.*Muk+sqr(Muk) );
}
// The name of this function is misleading
// scale here is defined as sqr(scale) = sqr(qi+qj)
// Here, scale is Q
Energy FFMassiveKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
double z=split.lastSplittingParameters()[0];
// masses
Energy2 mi2 = ZERO;
// g->gg and g->qqbar
if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
mi2 = sqr(split.emitterData()->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = sqr(split.emitterMass());
}
Energy2 m2 = sqr(split.emissionData()->mass());
Energy2 pt2 = z*(1.-z)*sqr(scale) - (1.-z)*mi2 - z*m2;
assert(pt2 >= ZERO);
return sqrt(pt2);
}
// This is simply the inverse of PtFromQ
Energy FFMassiveKinematics::QFromPt(Energy pt, const DipoleSplittingInfo& split) const {
double z=split.lastSplittingParameters()[0];
// masses
Energy2 mi2 = ZERO;
// g->gg and g->qqbar
if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
mi2 = sqr( split.emitterData()->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = sqr(split.emitterMass());
}
Energy2 m2 = sqr(split.emissionData()->mass());
Energy2 Q2 = (sqr(pt) + (1.-z)*mi2 + z*m2)/(z*(1.-z));
return sqrt(Q2);
}
double FFMassiveKinematics::ptToRandom(Energy pt, Energy,
double,double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
}
// SW, 14/02/2019: Tidied to match thesis
bool FFMassiveKinematics::generateSplitting(double kappa, double xi, double rphi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel&) {
// Scale 's' and masses
Energy2 Qijk = sqr(info.scale());
Energy2 mij2 = sqr(info.emitterMass());
Energy2 Mk2 = sqr(info.spectatorMass());
// To solve issue with scale during presampling
// need to enforce that Qijk-mij2-mk2 = 2*pij.pk > 0.
// Combine checks by comparing against square root
if ( Qijk-mij2-Mk2 < sqrt(4.*mij2*Mk2) ) {
jacobian(0.0);
return false;
}
Energy2 mk2 = Mk2;
Energy2 mi2 = ZERO;
// g->gg and g->qqbar
if ( abs(info.emitterData()->id()) == abs(info.emissionData()->id()) ) {
mi2 = sqr(info.emitterData()->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = mij2;
}
Energy2 mj2 = sqr(info.emissionData()->mass());
// Calculate pt
Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
Energy2 pt2 = sqr(pt);
if ( pt > info.hardPt() || pt < IRCutoff() ) {
jacobian(0.0);
return false;
}
// Generate z
double z;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
z = xi;
}
else {
z = exp(xi)/(1.+exp(xi));
}
}
else {
z = 1.-exp(-xi);
}
// new: 2011-08-31
// 2011-11-08: this does happen
if( (sqrt(mi2)+sqrt(mj2)+sqrt(mk2))/ sqrt(Qijk) > 1. ){
jacobian(0.0);
return false;
}
// Limits on z.
// Phasespace constraint to incorporate ptMax.
Energy hard = info.hardPt();
Energy2 sqrRootQijkMk = sqr(sqrt(Qijk)-sqrt(mk2));
if(openZBoundaries()>0){
// From ptMax(..)
hard = rootOfKallen(mi2, mj2, sqrRootQijkMk) / ( 2.*sqrt(sqrRootQijkMk) );
assert(pt<=hard);
}
double ptRatio = sqrt(1.-sqr(pt/hard));
double zp1 = ( mi2 - mj2 + sqrRootQijkMk +
rootOfKallen(mi2,mj2,sqrRootQijkMk) * ptRatio )
/ 2. / sqrRootQijkMk ;
double zm1 = ( mi2 - mj2 + sqrRootQijkMk -
rootOfKallen(mi2,mj2,sqrRootQijkMk) * ptRatio )
/ 2. / sqrRootQijkMk ;
if ( z > zp1 || z < zm1 ) {
jacobian(0.0);
return false;
}
// Calculate y
Energy2 sbar = Qijk - mi2 - mj2 - mk2;
double y = (pt2 + sqr(1.-z)*mi2 + sqr(z)*mj2)
/ sbar / z / (1.-z);
// Kinematic phasespace boundaries for y.
// Same as in Dittmaier hep-ph/9904440v2 (equivalent to CS).
double ym = 2.*sqrt(mi2)*sqrt(mj2)/sbar;
double yp = 1. - 2.*sqrt(mk2)*sqrt(sqrRootQijkMk) / sbar;
if ( y < ym || y > yp ) {
jacobian(0.0);
return false;
}
// Virtuality of emitted pair and other invariant scale
Energy2 Qij2 = (pt2 + (1.-z)*mi2 + z*mj2)
/ z / (1.-z);
Energy2 sijk = 0.5*( Qijk - mij2 - Mk2 + rootOfKallen(Qijk,mij2,mk2) );
// Calculate xk and xij
double lambdaIJ = 1. + (mij2/sijk);
double lambdaK = 1. + (mk2/sijk);
double fac1 = lambdaIJ*lambdaK + (mk2 - Qij2)/sijk;
double xk =
( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*mk2/sijk ) )
/ 2. / lambdaK ;
double xij = 1. - mk2*(1.-xk) / xk / sijk;
// Calculate zi
double zi =
( z*xij*xk*sijk + mk2*(pt2+mi2) / (z*xij*xk*sijk) )
/ (1.-y) / sbar;
// Limits on zi
double facA = (2.*mi2 + sbar*y) / 2. / (mi2 + mj2 + sbar*y);
// viji*vijk
double facB =
sqrt( (sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk) *
(sqr(sbar)*sqr(y) - 4.*mi2*mj2))
/ sbar / (1.-y) / (sbar*y + 2.*mi2);
double zim = facA * (1. - facB);
double zip = facA * (1. + facB);
if ( zi < zim || zi > zip ) {
jacobian(0.0);
return false;
}
double mapZJacobian;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
mapZJacobian = 1.;
}
else {
mapZJacobian = z*(1.-z);
}
}
else {
mapZJacobian = 1.-z;
}
// Compute and store the jacobian
double jac = 0.0;
jac = sbar / rootOfKallen(Qijk,mij2,mk2) * (1.-y) / ( 1. + (mi2 + mj2 - mij2)/sbar/y )
* (pt2 / (pt2 + sqr(1.-z)*mi2+sqr(z)*mj2))
* abs(1. - 2.*mk2*Qij2 / (sbar*(1.-y)*xij*xk*sijk));
jacobian(jac * mapZJacobian * 2. * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()) );
// Record the physical variables, as used by the CS kernel definitions
double phi = 2.*Constants::pi*rphi;
lastPt(pt);
lastZ(z);
lastPhi(phi);
// Record zi for use in kinematics generation and kernel evaluation
splittingParameters().clear();
splittingParameters().push_back(zi);
if ( theMCCheck ) {
theMCCheck->book(1.,1.,info.scale(),info.hardPt(),pt,z,jacobian());
}
return true;
}
// revised 2011-08-22
// revised 2011-11-06
// revised with new FF kinematics in 2016 - SW
// SW, 14/02/2019: Tidied to match thesis
void FFMassiveKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
Energy2 pt2 = sqr(pt);
// Masses
Energy2 mij2 = sqr(dInfo.emitterMass());
Energy2 Mk2 = sqr(dInfo.spectatorMass());
Energy2 mk2 = Mk2;
Energy2 mi2 = ZERO;
// g->gg and g->qqbar
if ( abs(dInfo.emitterData()->id()) == abs(dInfo.emissionData()->id()) ) {
mi2 = sqr(dInfo.emitterData()->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = mij2;
}
Energy2 mj2 = sqr(dInfo.emissionData()->mass());
// Scales
Energy2 Qijk = sqr(dInfo.scale());
Energy2 Qij2 = (pt2 + (1.-z)*mi2 + z*mj2) / z / (1.-z);
Energy2 sijk = 0.5*( Qijk - mij2 - Mk2 + rootOfKallen(Qijk,mij2,Mk2) );
Energy4 sijk2 = sqr(sijk);
// Calculate xk and xij
double lambdaIJ = 1. + (mij2/sijk);
double lambdaK = 1. + (mk2/sijk);
double fac1 = lambdaIJ*lambdaK + (mk2 - Qij2)/sijk;
double xk =
( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*mk2/sijk ) )
/ 2. / lambdaK ;
double xij = 1. - mk2*(1.-xk) / xk / sijk;
// Construct reference momenta nk and nij
Lorentz5Momentum nij = ( sijk2 / (sijk2-mij2*Mk2) ) * (pEmitter - (mij2/sijk)*pSpectator);
Lorentz5Momentum nk = ( sijk2 / (sijk2-mij2*Mk2) ) * (pSpectator - (Mk2/sijk)*pEmitter);
// Construct qij, qk, qi and qj
Lorentz5Momentum qij = xij*nij + (mij2/(xij*sijk))*nk;
Lorentz5Momentum qk = xk*nk + (Mk2/(xk*sijk))*nij;
Lorentz5Momentum qt = getKt(pEmitter, pSpectator, pt, dInfo.lastPhi());
// For clarity, following notation in notes:
Lorentz5Momentum qi = z*qij + ((pt2 + mi2 - z*z*mij2)/(xij*sijk*z))*nk + qt;
Lorentz5Momentum qj = (1.-z)*qij + ((pt2 + mj2 - sqr(1.-z)*mij2)/(xij*sijk*(1.-z)))*nk - qt;
qi.setMass(sqrt(mi2));
qi.rescaleEnergy();
qj.setMass(sqrt(mj2));
qj.rescaleEnergy();
qk.setMass(sqrt(mk2));
qk.rescaleEnergy();
emitterMomentum(qi);
emissionMomentum(qj);
spectatorMomentum(qk);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FFMassiveKinematics::persistentOutput(PersistentOStream &) const {
//os << ;
}
void FFMassiveKinematics::persistentInput(PersistentIStream &, int) {
//is >> ;
}
ClassDescription<FFMassiveKinematics> FFMassiveKinematics::initFFMassiveKinematics;
// Definition of the static class description member.
void FFMassiveKinematics::Init() {
static ClassDocumentation<FFMassiveKinematics> documentation
("FFMassiveKinematics implements massive splittings "
"off a final-final dipole.");
}
diff --git a/Shower/Dipole/Kinematics/FFMassiveKinematics.h b/Shower/Dipole/Kinematics/FFMassiveKinematics.h
--- a/Shower/Dipole/Kinematics/FFMassiveKinematics.h
+++ b/Shower/Dipole/Kinematics/FFMassiveKinematics.h
@@ -1,299 +1,291 @@
// -*- C++ -*-
//
// FFMassiveKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FFMassiveKinematics_H
#define HERWIG_FFMassiveKinematics_H
//
// This is the declaration of the FFMassiveKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Stephen Webster
*
* \brief FFMassiveKinematics implements massive splittings
* off a final-final dipole.
*
*/
class FFMassiveKinematics: public DipoleSplittingKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FFMassiveKinematics();
- /**
- * The destructor.
- */
- virtual ~FFMassiveKinematics();
- //@}
-
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy,
const DipoleSplittingInfo&,
const DipoleSplittingKernel&) const {
return {0.0,1.0};
}
/**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double, double,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
tPPtr emitter, tPPtr spectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for massive
// dipoles, for now anyway.
assert(false);
return ZERO;
}
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for massive
// dipoles, for now anyway.
assert(false);
return ZERO;
}
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& dIndex,
const DipoleSplittingKernel& split);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline T rootOfKallen (T a, T b, T c) const {
if ( a*a + b*b + c*c - 2.*(a*b + a*c + b*c) > ZERO )
return sqrt(a*a + b*b + c*c - 2.*(a*b + a*c + b*c) ) ;
else
return ZERO; }
/**
* Perform a rotation on both momenta such that the first one will
* point along the (positive) z axis. Rotate back to the original
* reference frame by applying rotateUz(returnedVector) to each momentum.
*/
ThreeVector<double> rotateToZ (Lorentz5Momentum& pTarget, Lorentz5Momentum& p1){
ThreeVector<double> oldAxis = pTarget.vect().unit();
double ct = oldAxis.z(); double st = sqrt( 1.-sqr(ct) ); // cos,sin(theta)
double cp = oldAxis.x()/st; double sp = oldAxis.y()/st; // cos,sin(phi)
pTarget.setZ( pTarget.vect().mag() ); pTarget.setX( 0.*GeV ); pTarget.setY( 0.*GeV );
Lorentz5Momentum p1old = p1;
p1.setX( sp*p1old.x() - cp*p1old.y() );
p1.setY( ct*cp*p1old.x() + ct*sp*p1old.y() - st*p1old.z() );
p1.setZ( st*cp*p1old.x() + st*sp*p1old.y() + ct*p1old.z() );
return oldAxis;
}
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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FFMassiveKinematics> initFFMassiveKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FFMassiveKinematics & operator=(const FFMassiveKinematics &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FFMassiveKinematics. */
template <>
struct BaseClassTrait<Herwig::FFMassiveKinematics,1> {
/** Typedef of the first base class of FFMassiveKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FFMassiveKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FFMassiveKinematics>
: public ClassTraitsBase<Herwig::FFMassiveKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FFMassiveKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* FFMassiveKinematics is implemented. It may also include several, space-separated,
* libraries if the class FFMassiveKinematics 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_FFMassiveKinematics_H */
diff --git a/Shower/Dipole/Kinematics/FILightKinematics.cc b/Shower/Dipole/Kinematics/FILightKinematics.cc
--- a/Shower/Dipole/Kinematics/FILightKinematics.cc
+++ b/Shower/Dipole/Kinematics/FILightKinematics.cc
@@ -1,187 +1,185 @@
// -*- C++ -*-
//
// FILightKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FILightKinematics class.
//
#include "FILightKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
using namespace Herwig;
FILightKinematics::FILightKinematics()
: DipoleSplittingKinematics() {}
-FILightKinematics::~FILightKinematics() {}
-
IBPtr FILightKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FILightKinematics::fullclone() const {
return new_ptr(*this);
}
Energy FILightKinematics::ptMax(Energy dScale,
double, double specX,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return dScale * sqrt((1.-specX)/specX) /2.;
}
Energy FILightKinematics::QMax(Energy dScale,
double, double specX,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return dScale * sqrt((1.-specX)/specX);
}
Energy FILightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale*sqrt(z*(1.-z));
}
Energy FILightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale/sqrt(z*(1.-z));
}
pair<double,double> FILightKinematics::zBoundaries(Energy pt,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel&) const {
Energy hard=dInfo.hardPt();
if(openZBoundaries()==1)
hard=dInfo.scale()*sqrt((1.-dInfo.spectatorX())/dInfo.spectatorX())/2.;
if(openZBoundaries()==2)
hard=dInfo.scale()*min(1.,sqrt((1.-dInfo.spectatorX())/dInfo.spectatorX())/2.);
if(hard<pt)return {0.5,0.5};
double s = sqrt(1.-sqr(pt/hard));
return {0.5*(1.-s),0.5*(1.+s)};
}
bool FILightKinematics::generateSplitting(double kappa, double xi, double rphi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel& split) {
if ( info.spectatorX() < xMin() ) {
jacobian(0.0);
return false;
}
double weight = 1.0;
Energy pt = generatePt(kappa,info.scale(),
info.emitterX(),info.spectatorX(),
info.index(),split,
weight);
if ( pt < IRCutoff() || pt > info.hardPt() ) {
jacobian(0.0);
return false;
}
double z = 0.0;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
z = generateZ(xi,pt,FlatZ,
info,split,weight);
} else {
z = generateZ(xi,pt,OneOverZOneMinusZ,
info,split,weight);
}
} else {
z = generateZ(xi,pt,OneOverOneMinusZ,
info,split,weight);
}
double x = 1./(1.+sqr(pt/info.scale())/(z*(1.-z)));
if ( z < 0.0 || z > 1.0 ||
x < info.spectatorX() || x > 1.0 ) {
jacobian(0.0);
return false;
}
double phi = 2.*Constants::pi*rphi;
jacobian(weight);
lastPt(pt);
lastZ(z);
lastPhi(phi);
lastSpectatorZ(x);
if ( theMCCheck )
theMCCheck->book(1.,info.spectatorX(),info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
void FILightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
Energy pt = dInfo.lastPt();
double z = dInfo.lastZ();
double x = 1./(1.+sqr(pt/dInfo.scale())/(z*(1.-z)));
Lorentz5Momentum kt =
getKt(pEmitter, pSpectator, pt, dInfo.lastPhi(), true);
Lorentz5Momentum em = z*pEmitter + (1.-z)*((1.-x)/x)*pSpectator + kt;
Lorentz5Momentum emm = (1.-z)*pEmitter + z*((1.-x)/x)*pSpectator - kt;
Lorentz5Momentum spe = (1./x)*pSpectator;
em.setMass(ZERO);
em.rescaleEnergy();
emm.setMass(ZERO);
emm.rescaleEnergy();
spe.setMass(ZERO);
spe.rescaleEnergy();
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FILightKinematics::persistentOutput(PersistentOStream & ) const {
}
void FILightKinematics::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FILightKinematics> FILightKinematics::initFILightKinematics;
// Definition of the static class description member.
void FILightKinematics::Init() {
static ClassDocumentation<FILightKinematics> documentation
("FILightKinematics implements massless splittings "
"off a final-initial dipole.");
}
diff --git a/Shower/Dipole/Kinematics/FILightKinematics.h b/Shower/Dipole/Kinematics/FILightKinematics.h
--- a/Shower/Dipole/Kinematics/FILightKinematics.h
+++ b/Shower/Dipole/Kinematics/FILightKinematics.h
@@ -1,200 +1,192 @@
// -*- C++ -*-
//
// FILightKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FILightKinematics_H
#define HERWIG_FILightKinematics_H
//
// This is the declaration of the FILightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief FILightKinematics implements massless splittings
* off a final-initial dipole.
*
*/
class FILightKinematics: public DipoleSplittingKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FILightKinematics();
- /**
- * The destructor.
- */
- virtual ~FILightKinematics();
- //@}
-
public:
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel&) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel&) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy pt,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& dIndex,
const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FILightKinematics> initFILightKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FILightKinematics & operator=(const FILightKinematics &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FILightKinematics. */
template <>
struct BaseClassTrait<Herwig::FILightKinematics,1> {
/** Typedef of the first base class of FILightKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FILightKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FILightKinematics>
: public ClassTraitsBase<Herwig::FILightKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FILightKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* FILightKinematics is implemented. It may also include several, space-separated,
* libraries if the class FILightKinematics 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_FILightKinematics_H */
diff --git a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.cc b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.cc
--- a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.cc
+++ b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.cc
@@ -1,452 +1,450 @@
// -*- C++ -*-
//
// FIMassiveDecayKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FIMassiveDecayKinematics class.
//
#include "FIMassiveDecayKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
#include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
#include "ThePEG/Interface/Switch.h"
using namespace Herwig;
FIMassiveDecayKinematics::FIMassiveDecayKinematics()
: DipoleSplittingKinematics() {}
-FIMassiveDecayKinematics::~FIMassiveDecayKinematics() {}
-
IBPtr FIMassiveDecayKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FIMassiveDecayKinematics::fullclone() const {
return new_ptr(*this);
}
pair<double,double> FIMassiveDecayKinematics::kappaSupport(const DipoleSplittingInfo&) const {
return {0.0,1.0};
}
pair<double,double> FIMassiveDecayKinematics::xiSupport(const DipoleSplittingInfo& split) const {
double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
if ( split.index().emitterData()->id() == ParticleID::g ) {
if ( split.emissionData()->id() != ParticleID::g ){
return {0.5*(1.-c),0.5*(1.+c)};
}
double b = log((1.+c)/(1.-c));
return {-b,b};
}
return {-log(0.5*(1.+c)),-log(0.5*(1.-c))};
}
Energy FIMassiveDecayKinematics::dipoleScale(const Lorentz5Momentum&,
const Lorentz5Momentum& pSpectator) const {
return pSpectator.m();
}
Energy FIMassiveDecayKinematics::recoilMassKin(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const {
Lorentz5Momentum pk = pSpectator - pEmitter;
Energy pkmass = pk.m();
return pkmass;
}
Energy FIMassiveDecayKinematics::ptMax(Energy dScale,
double, double,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const {
DipoleIndex ind = dInfo.index();
double mui2 = 0.;
// g->gg and g->qqbar
if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
mui2 = sqr(split.emitter(ind)->mass() / dScale);
}
// Otherwise have X->Xg (should work for SUSY)
else {
mui2 = sqr(dInfo.emitterMass()/dScale);
}
double muj2 = sqr( split.emission(ind)->mass() / dScale );
// Mass of recoil system
double muk = dInfo.recoilMass() / dScale;
return rootOfKallen( mui2, muj2, sqr(1.-muk) ) / ( 2.-2.*muk ) * dScale;
}
Energy FIMassiveDecayKinematics::ptMax(Energy dScale,
double, double,
const DipoleIndex& ind,
const DipoleSplittingKernel& split,
tPPtr emitter, tPPtr spectator) const {
double mui2 = 0.;
// g->gg and g->qqbar
if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
mui2 = sqr(split.emitter(ind)->mass() / dScale);
}
// Otherwise have X->Xg (should work for SUSY)
else {
mui2 = sqr(emitter->mass()/dScale);
}
double muj2 = sqr(split.emission(ind)->mass() / dScale);
// Mass of recoil system
double muk = recoilMassKin(emitter->momentum(),spectator->momentum()) / dScale;
return rootOfKallen( mui2, muj2, sqr(1.-muk) ) / ( 2.-2.*muk ) * dScale;
}
Energy FIMassiveDecayKinematics::QMax(Energy dScale,
double, double,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel&) const {
assert(false && "implementation missing");
// Mass of recoil system
double Muk2 = sqr( dInfo.recoilMass() / dScale );
double Muk = sqrt( Muk2 );
return dScale * ( 1.-2.*Muk+Muk2 );
}
// The name of this function is misleading
// scale here is defined as sqr(scale) = sqr(qi+qj)
// Here, scale is Q
Energy FIMassiveDecayKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
double zPrime = split.lastSplittingParameters()[0];
// masses
Energy2 mi2 = ZERO;
// g->gg and g->qqbar
if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
mi2 = sqr( split.emitterData()->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = sqr(split.emitterMass());
}
Energy2 m2 = sqr(split.emissionData()->mass());
Energy2 pt2 = zPrime*(1.-zPrime)*sqr(scale) - (1-zPrime)*mi2 - zPrime*m2;
assert(pt2 >= ZERO);
return sqrt(pt2);
}
// This is simply the inverse of PtFromQ
Energy FIMassiveDecayKinematics::QFromPt(Energy pt, const DipoleSplittingInfo& split) const {
double zPrime = split.lastSplittingParameters()[0];
// masses
Energy2 mi2 = ZERO;
// g->gg and g->qqbar
if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
mi2 = sqr( split.emitterData()->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = sqr(split.emitterMass());
}
Energy2 m2 = sqr(split.emissionData()->mass());
Energy2 Q2 = (sqr(pt) + (1-zPrime)*mi2 + zPrime*m2)/(zPrime*(1.-zPrime));
return sqrt(Q2);
}
double FIMassiveDecayKinematics::ptToRandom(Energy pt, Energy,
double,double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
}
// SW, 14/02/2019: Tidied to match thesis
bool FIMassiveDecayKinematics::generateSplitting(double kappa, double xi, double rphi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel&) {
// Scale 's' and masses
Energy2 Qijk = sqr(info.scale());
Energy2 mij2 = sqr(info.emitterMass());
Energy2 Mk2 = sqr(info.recoilMass());
// To solve issue with scale during presampling
// need to enforce that Qijk-mij2-mk2 = 2*pij.pk > 0.
// Combine checks by comparing against square root
if ( Qijk-mij2-Mk2 < sqrt(4.*mij2*Mk2) ) {
jacobian(0.0);
return false;
}
Energy2 mk2 = Mk2;
Energy2 mi2 = ZERO;
// g->gg and g->qqbar
if ( abs(info.emitterData()->id()) == abs(info.emissionData()->id()) ) {
mi2 = sqr(info.emitterData()->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = mij2;
}
Energy2 mj2 = sqr(info.emissionData()->mass());
// Calculate pt
Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
Energy2 pt2 = sqr(pt);
if ( pt > info.hardPt() || pt < IRCutoff() ) {
jacobian(0.0);
return false;
}
// Generate z
double z;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
z = xi;
}
else {
z = exp(xi)/(1.+exp(xi));
}
}
else {
z = 1.-exp(-xi);
}
// new: 2011-08-31
// 2011-11-08: this does happen
if( (sqrt(mi2)+sqrt(mj2)+sqrt(mk2))/ sqrt(Qijk) > 1. ){
jacobian(0.0);
return false;
}
// Limits on z.
// Phasespace constraint to incorporate ptMax.
Energy hard = info.hardPt();
Energy2 sqrRootQijkMk = sqr(sqrt(Qijk)-sqrt(mk2));
if(openZBoundaries()>0){
// From ptMax(..)
hard = rootOfKallen(mi2, mj2, sqrRootQijkMk) / ( 2.*sqrt(sqrRootQijkMk) );
assert(pt<=hard);
}
double ptRatio = sqrt(1.-sqr(pt/hard));
double zp1 = ( mi2 - mj2 + sqrRootQijkMk +
rootOfKallen(mi2,mj2,sqrRootQijkMk) * ptRatio )
/ 2. / sqrRootQijkMk ;
double zm1 = ( mi2 - mj2 + sqrRootQijkMk -
rootOfKallen(mi2,mj2,sqrRootQijkMk) * ptRatio )
/ 2. / sqrRootQijkMk ;
if ( z > zp1 || z < zm1 ) {
jacobian(0.0);
return false;
}
// Calculate y
Energy2 sbar = Qijk - mi2 - mj2 - mk2;
double y = (pt2 + sqr(1.-z)*mi2 + sqr(z)*mj2)
/ sbar / z / (1.-z);
// Kinematic phasespace boundaries for y.
// Same as in Dittmaier hep-ph/9904440v2 (equivalent to CS).
double ym = 2.*sqrt(mi2)*sqrt(mj2)/sbar;
double yp = 1. - 2.*sqrt(mk2)*sqrt(sqrRootQijkMk) / sbar;
if ( y < ym || y > yp ) {
jacobian(0.0);
return false;
}
// Virtuality of emitted pair and other invariant scale
Energy2 Qij2 = (pt2 + (1.-z)*mi2 + z*mj2) / z / (1.-z);
Energy2 sijk = 0.5*( Qijk - mij2 - Mk2 + rootOfKallen(Qijk,mij2,mk2) );
// Calculate xk and xij
double lambdaIJ = 1. + (mij2/sijk);
double lambdaK = 1. + (mk2/sijk);
double fac1 = lambdaIJ*lambdaK + (mk2 - Qij2)/sijk;
double xk =
( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*mk2/sijk ) )
/ 2. / lambdaK ;
double xij = 1. - mk2*(1.-xk) / xk / sijk;
// Calculate zi
double zi =
( z*xij*xk*sijk + mk2*(pt2+mi2) / (z*xij*xk*sijk) )
/ (1.-y) / sbar;
// Limits on zi
double facA = (2.*mi2 + sbar*y) / 2. / (mi2 + mj2 + sbar*y);
// viji*vijk
double facB =
sqrt( (sqr(2.*mk2 + sbar*(1.-y)) - 4.*mk2*Qijk) *
(sqr(sbar)*sqr(y) - 4.*mi2*mj2))
/ sbar / (1.-y) / (sbar*y + 2.*mi2);
double zim = facA * (1. - facB);
double zip = facA * (1. + facB);
if ( zi < zim || zi > zip ) {
jacobian(0.0);
return false;
}
double mapZJacobian;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
mapZJacobian = 1.;
}
else {
mapZJacobian = z*(1.-z);
}
}
else {
mapZJacobian = 1.-z;
}
// Compute and store the jacobian
double jac = 0.0;
jac = sbar / rootOfKallen(Qijk,mij2,mk2) * (1.-y) / ( 1. + (mi2 + mj2 - mij2)/sbar/y )
* (pt2 / (pt2 + sqr(1.-z)*mi2+sqr(z)*mj2))
* abs(1. - 2.*mk2*Qij2 / (sbar*(1.-y)*xij*xk*sijk));
jacobian(jac * mapZJacobian * 2. * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()) );
// Record the physical variables, as used by the CS kernel definitions
double phi = 2.*Constants::pi*rphi;
lastPt(pt);
lastZ(z);
lastPhi(phi);
// Record zi for use in kinematics generation and kernel evaluation
splittingParameters().clear();
splittingParameters().push_back(zi);
if ( theMCCheck ) {
theMCCheck->book(1.,1.,info.scale(),info.hardPt(),pt,z,jacobian());
}
return true;
}
// SW, 14/02/2019: Tidied to match thesis
void FIMassiveDecayKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
Energy2 pt2 = sqr(pt);
// Momentum of the recoil system
Lorentz5Momentum pk = pSpectator - pEmitter;
Lorentz5Momentum pij = pEmitter;
// scaled masses
Energy2 mij2 = sqr(dInfo.emitterMass());
Energy2 Mk2 = sqr(dInfo.recoilMass());
Energy2 mk2 = Mk2;
Energy2 mi2 = ZERO;
// g->gg and g->qqbar
if ( abs(dInfo.emitterData()->id()) == abs(dInfo.emissionData()->id()) ) {
mi2 = sqr(dInfo.emitterData()->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = mij2;
}
Energy2 mj2 = sqr(dInfo.emissionData()->mass());
// Scales
Energy2 Qijk = sqr(dInfo.scale());
Energy2 Qij2 = (pt2 + (1.-z)*mi2 + z*mj2) / z / (1.-z);
Energy2 sijk = 0.5*( Qijk - mij2 - mk2 + rootOfKallen(Qijk,mij2,mk2) );
Energy4 sijk2 = sqr(sijk);
// Calculate xk and xij
double lambdaIJ = 1. + (mij2/sijk);
double lambdaK = 1. + (mk2/sijk);
double fac1 = lambdaIJ*lambdaK + (mk2 - Qij2)/sijk;
double xk =
( fac1 + sqrt( sqr(fac1) - 4.*lambdaIJ*lambdaK*mk2/sijk ) )
/ 2. / lambdaK ;
double xij = 1. - mk2*(1.-xk) / xk / sijk;
// Construct reference momenta nk and nij
Lorentz5Momentum nij = ( sijk2 / (sijk2-mij2*Mk2) ) * (pij - (mij2/sijk)*pk);
Lorentz5Momentum nk = ( sijk2 / (sijk2-mij2*Mk2) ) * (pk - (Mk2/sijk)*pij);
// Construct qij, qk, qi and qj
Lorentz5Momentum qij = xij*nij + (mij2/(xij*sijk))*nk;
Lorentz5Momentum qk = xk*nk + (Mk2/(xk*sijk))*nij;
Lorentz5Momentum qt = getKt(pij, pk, pt, dInfo.lastPhi());
// No need to actually calculate nt and wt:
Lorentz5Momentum qi = z*qij + ((pt2 + mi2 - z*z*mij2)/(xij*sijk*z))*nk + qt;
Lorentz5Momentum qj = (1.-z)*qij + ((pt2 + mj2 - sqr(1.-z)*mij2)/(xij*sijk*(1.-z)))*nk - qt;
qi.setMass(sqrt(mi2));
qi.rescaleEnergy();
qj.setMass(sqrt(mj2));
qj.rescaleEnergy();
emitterMomentum(qi);
emissionMomentum(qj);
spectatorMomentum(pSpectator);
// Required for absorbing recoil in DipoleEventRecord::update
splitRecoilMomentum(qk);
}
Lorentz5Momentum FIMassiveDecayKinematics::nVector(const Lorentz5Momentum& pEmitter, const Lorentz5Momentum& pSpectator, const DipoleSplittingInfo&) const {
return (pSpectator-pEmitter);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIMassiveDecayKinematics::persistentOutput(PersistentOStream &) const {
//os << ;
}
void FIMassiveDecayKinematics::persistentInput(PersistentIStream &, int) {
//is >> ;
}
ClassDescription<FIMassiveDecayKinematics> FIMassiveDecayKinematics::initFIMassiveDecayKinematics;
// Definition of the static class description member.
void FIMassiveDecayKinematics::Init() {
static ClassDocumentation<FIMassiveDecayKinematics> documentation
("FIMassiveDecayKinematics implements implements massive splittings "
"off a final-initial decay dipole.");
}
diff --git a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h
--- a/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h
+++ b/Shower/Dipole/Kinematics/FIMassiveDecayKinematics.h
@@ -1,327 +1,319 @@
// -*- C++ -*-
//
// FIMassiveDecayKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FIMassiveDecayKinematics_H
#define HERWIG_FIMassiveDecayKinematics_H
//
// This is the declaration of the FIMassiveDecayKinematics class.
//
#include "DipoleSplittingKinematics.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Utilities/UtilityBase.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Stephen Webster
*
* \brief FIMassiveDecayKinematics implements massive splittings
* off a final-initial decay dipole.
*
*/
class FIMassiveDecayKinematics: public DipoleSplittingKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIMassiveDecayKinematics();
- /**
- * The destructor.
- */
- virtual ~FIMassiveDecayKinematics();
- //@}
-
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy,
const DipoleSplittingInfo&,
const DipoleSplittingKernel&) const {
return {0.0,1.0};
}
/**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the mass of the system absorbing
* the recoil in the dipole splitting.
* This is only used in decay dipoles.
*/
virtual Energy recoilMassKin(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double, double,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
tPPtr emitter, tPPtr spectator) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for the decays.
assert(false);
return ZERO;
}
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for the decays.
assert(false);
return ZERO;
}
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel& split);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
/**
* Return the nVector as required for spin correlations.
*/
virtual Lorentz5Momentum nVector(const Lorentz5Momentum& pEmitter, const Lorentz5Momentum& pSpectator, const DipoleSplittingInfo& dInfo) const;
/*
* Return true if this splitting is of a dipole which contains
* a decayed parton and requires the remnant to absorb the recoil.
*/
virtual bool isDecay() const { return true; }
/**
* Perform the recoil in the case of a decayed parton
*/
virtual void decayRecoil ( PList& recoilSystem ) {
PList::iterator beginRecoil = recoilSystem.begin();
PList::iterator endRecoil = recoilSystem.end();
// This is the final momentum that we must transform the system to
const Momentum3 transformMom = splitRecoilMomentum().vect();
// Calculate required Lorentz rotation
Lorentz5Momentum sum = ThePEG::UtilityBase::sumMomentum(beginRecoil, endRecoil);
LorentzRotation rot = ThePEG::UtilityBase::transformToCMS(sum);
rot = ThePEG::UtilityBase::transformFromCMS
(Lorentz5Momentum(transformMom, sqrt(transformMom.mag2() + sum.m2()))) * rot;
// Transform the particle spinInfo if required
for ( const auto& p : recoilSystem ) {
if ( p->spinInfo() )
p->spinInfo()->transform(p->momentum(),rot);
}
ThePEG::UtilityBase::transform(beginRecoil, endRecoil, rot );
}
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline T rootOfKallen (T a, T b, T c) const {
if ( a*a + b*b + c*c - 2.*(a*b + a*c + b*c) > ZERO )
return sqrt(a*a + b*b + c*c - 2.*(a*b + a*c + b*c) ) ;
else
return 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).
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIMassiveDecayKinematics> initFIMassiveDecayKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIMassiveDecayKinematics & operator=(const FIMassiveDecayKinematics &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIMassiveDecayKinematics. */
template <>
struct BaseClassTrait<Herwig::FIMassiveDecayKinematics,1> {
/** Typedef of the first base class of FIMassiveDecayKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIMassiveDecayKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIMassiveDecayKinematics>
: public ClassTraitsBase<Herwig::FIMassiveDecayKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIMassiveDecayKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* FIMassiveDecayKinematics is implemented. It may also include several, space-separated,
* libraries if the class FIMassiveDecayKinematics 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_FIMassiveDecayKinematics_H */
diff --git a/Shower/Dipole/Kinematics/FIMassiveKinematics.cc b/Shower/Dipole/Kinematics/FIMassiveKinematics.cc
--- a/Shower/Dipole/Kinematics/FIMassiveKinematics.cc
+++ b/Shower/Dipole/Kinematics/FIMassiveKinematics.cc
@@ -1,385 +1,383 @@
// -*- C++ -*-
//
// FIMassiveKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 FIMassiveKinematics class.
//
#include "FIMassiveKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
#include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
using namespace Herwig;
FIMassiveKinematics::FIMassiveKinematics()
: DipoleSplittingKinematics() {}
-FIMassiveKinematics::~FIMassiveKinematics() {}
-
IBPtr FIMassiveKinematics::clone() const {
return new_ptr(*this);
}
IBPtr FIMassiveKinematics::fullclone() const {
return new_ptr(*this);
}
pair<double,double> FIMassiveKinematics::kappaSupport(const DipoleSplittingInfo&) const {
return {0.0,1.0};
}
pair<double,double> FIMassiveKinematics::xiSupport(const DipoleSplittingInfo& split) const {
double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
if ( split.index().emitterData()->id() == ParticleID::g ) {
if ( split.emissionData()->id() != ParticleID::g )
return {0.5*(1.-c),0.5*(1.+c)};
double b = log((1.+c)/(1.-c));
return {-b,b};
}
return {-log(0.5*(1.+c)),-log(0.5*(1.-c))};
}
// sbar
Energy FIMassiveKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const {
return sqrt(2.*(pEmitter*pSpectator));
}
Energy FIMassiveKinematics::ptMax(Energy dScale,
double, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const {
DipoleIndex ind = dInfo.index();
Energy2 mij2 = sqr(dInfo.emitterMass());
Energy2 mi2 = ZERO;
// g->gg and g->qqbar
if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
mi2 = sqr(split.emitter(ind)->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = mij2;
}
Energy2 mj2 = sqr(split.emission(ind)->mass());
Energy2 sPrime = sqr(dScale) * (1.-specX)/specX + mij2;
return .5 * sqrt(sPrime) * rootOfKallen( sPrime/sPrime, mi2/sPrime, mj2/sPrime );
}
Energy FIMassiveKinematics::ptMax(Energy dScale,
double, double specX,
const DipoleIndex& ind,
const DipoleSplittingKernel& split,
tPPtr emitter, tPPtr) const {
Energy2 mij2 = sqr(emitter->mass());
Energy2 mi2 = ZERO;
// g->gg and g->qqbar
if ( abs(split.emitter(ind)->id()) == abs(split.emission(ind)->id()) ) {
mi2 = sqr(split.emitter(ind)->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = mij2;
}
Energy2 mj2 = sqr(split.emission(ind)->mass());
Energy2 sPrime = sqr(dScale) * (1.-specX)/specX + mij2;
return .5 * sqrt(sPrime) * rootOfKallen( sPrime/sPrime, mi2/sPrime, mj2/sPrime );
}
Energy FIMassiveKinematics::QMax(Energy dScale,
double, double specX,
const DipoleSplittingInfo&,
const DipoleSplittingKernel&) const {
generator()->log() << "FIMassiveKinematics::QMax called.\n" << flush;
assert(false && "implementation missing");
// this is sqrt( 2qi*q ) -> max;
return dScale * sqrt((1.-specX)/specX);
}
Energy FIMassiveKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
// from Martin's thesis
double z = split.lastZ();
// masses
Energy2 mi2 = ZERO;;
if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
mi2 = sqr(split.emitterData()->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = sqr(split.emitterMass());
}
Energy2 mj2 = sqr(split.emissionData()->mass());
Energy2 pt2 = z*(1.-z)*sqr(scale) - (1.-z)*mi2 - z*mj2;
assert(pt2 >= ZERO);
return sqrt(pt2);
}
Energy FIMassiveKinematics::QFromPt(Energy pt, const DipoleSplittingInfo& split) const {
// from Martin's thesis
double z = split.lastZ();
// masses
Energy2 mi2 = ZERO;;
if ( abs(split.emitterData()->id()) == abs(split.emissionData()->id()) ) {
mi2 = sqr(split.emitterData()->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = sqr(split.emitterMass());
}
Energy2 mj2 = sqr(split.emissionData()->mass());
Energy2 Q2 = (sqr(pt) + (1.-z)*mi2 + z*mj2)/(z*(1.-z));
return sqrt(Q2);
}
double FIMassiveKinematics::ptToRandom(Energy pt, Energy,
double,double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
}
bool FIMassiveKinematics::generateSplitting(double kappa, double xi, double rphi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel&) {
if ( info.spectatorX() < xMin() ) {
jacobian(0.0);
return false;
}
Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
if ( pt > info.hardPt() || pt < IRCutoff() ) {
jacobian(0.0);
return false;
}
double z;
double mapZJacobian;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
z = xi;
mapZJacobian = 1.;
} else {
z = exp(xi)/(1.+exp(xi));
mapZJacobian = z*(1.-z);
}
} else {
z = 1.-exp(-xi);
mapZJacobian = 1.-z;
}
// Construct mass squared variables
Energy2 mij2 = sqr(info.emitterMass());
Energy2 mi2 = ZERO;
// g->gg and g->qqbar
if ( abs(info.emitterData()->id()) == abs(info.emissionData()->id()) ) {
mi2 = sqr(info.emitterData()->mass());
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi2 = mij2;
}
Energy2 mj2 = sqr(info.emissionData()->mass());
Energy2 pt2 = sqr(pt);
// 2 pij.pb
Energy2 sbar = sqr(info.scale());
// Compute x
double x = 1. / ( 1. +
( pt2 + (1.-z)*mi2 + z*mj2 - z*(1.-z)*mij2 ) /
( z*(1.-z)*sbar ) );
// Check the limit on x
double xs = info.spectatorX();
if ( x < xs ) {
jacobian(0.0);
return false;
}
// Compute and check the z limits
Energy2 sPrime = sbar * (1.-xs)/xs + mij2;
Energy hard=info.hardPt();
if(openZBoundaries()==1){
hard=.5 * sqrt(sPrime) * rootOfKallen( sPrime/sPrime, mi2/sPrime, mj2/sPrime );
}
if(openZBoundaries()==2){
Energy2 s = mij2 - sbar;
hard=min(0.5*sqrt(sPrime) *
rootOfKallen( sPrime/sPrime, mi2/sPrime, mj2/sPrime ) ,
0.5*sqrt(s) *
rootOfKallen( s/s, mi2/s, mj2/s ));
}
double ptRatio = sqrt(1.-sqr(pt/hard));
double zm1 = .5*( 1.+(mi2-mj2)/sPrime - rootOfKallen(sPrime/sPrime,mi2/sPrime,mj2/sPrime) * ptRatio);
double zp1 = .5*( 1.+(mi2-mj2)/sPrime + rootOfKallen(sPrime/sPrime,mi2/sPrime,mj2/sPrime) * ptRatio);
if ( z > zp1 || z < zm1 ) {
jacobian(0.0);
return false;
}
// additional purely kinematic constraints from
// the integration limits in Catani-Seymour
double mui2CS = x*mi2/sbar;
double muj2CS = x*mj2/sbar;
double muij2CS = x*mij2/sbar;
// Limit on x
double xp = 1. + muij2CS - sqr(sqrt(mui2CS)+sqrt(muj2CS));
if (x > xp ) {
jacobian(0.0);
return false;
}
// Limit on z
double root = sqr(1.-x+muij2CS-mui2CS-muj2CS)-4.*mui2CS*muj2CS;
if( root < 0. && root>-1e-10 ) {
// assert(false);
root = 0.;
}
else if (root <0. ) {
jacobian(0.0);
return false;
}
root = sqrt(root);
double zm2 = .5*( 1.-x+muij2CS+mui2CS-muj2CS - root ) / (1.-x+muij2CS);
double zp2 = .5*( 1.-x+muij2CS+mui2CS-muj2CS + root ) / (1.-x+muij2CS);
if ( z > zp2 || z < zm2 ) {
jacobian(0.0);
return false;
}
// Store the splitting variables
double phi = 2.*Constants::pi*rphi;
// Compute and store the jacobian
double jacPt2 = 1. / ( 1. + (1.-z)*mi2/pt2 + z*mj2/pt2 - z*(1.-z)*mij2/pt2 );
jacobian( jacPt2 * mapZJacobian * 2.*log(0.5 * generator()->maximumCMEnergy()/IRCutoff()));
lastPt(pt);
lastZ(z);
lastPhi(phi);
lastSpectatorZ(x);
if ( theMCCheck )
theMCCheck->book(1.,info.spectatorX(),info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
void FIMassiveKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
// Get splitting variables
Energy pt = dInfo.lastPt();
double z = dInfo.lastZ();
// Compute sqr scales
Energy2 pt2 = sqr(pt);
Energy2 sbar = sqr(dInfo.scale());
// Construct mass squared variables
Energy2 mij2 = sqr(dInfo.emitterMass());
Energy mi = ZERO;
// g->gg and g->qqbar
if ( abs(dInfo.emitterData()->id()) == abs(dInfo.emissionData()->id()) ) {
mi = dInfo.emitterData()->mass();
}
// Otherwise have X->Xg (should work for SUSY)
else {
mi = dInfo.emitterMass();
}
Energy2 mi2 = sqr(mi);
Energy2 mj2 = sqr(dInfo.emissionData()->mass());
double xInv = ( 1. +
(pt2+(1.-z)*mi2+z*mj2-z*(1.-z)*mij2) /
(z*(1.-z)*sbar) );
Lorentz5Momentum kt = getKt(pEmitter, pSpectator, pt, dInfo.lastPhi(), true);
Lorentz5Momentum em = z*pEmitter +
(pt2+mi2-z*z*mij2)/(z*sbar)*pSpectator + kt;
Lorentz5Momentum emm = (1.-z)*pEmitter +
(pt2+mj2-sqr(1.-z)*mij2)/((1.-z)*sbar)*pSpectator - kt;
Lorentz5Momentum spe = xInv*pSpectator;
em.setMass(mi);
em.rescaleEnergy();
emm.setMass(dInfo.emissionData()->mass());
emm.rescaleEnergy();
spe.setMass(ZERO);
spe.rescaleEnergy();
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void FIMassiveKinematics::persistentOutput(PersistentOStream & ) const {
}
void FIMassiveKinematics::persistentInput(PersistentIStream & , int) {
}
ClassDescription<FIMassiveKinematics> FIMassiveKinematics::initFIMassiveKinematics;
// Definition of the static class description member.
void FIMassiveKinematics::Init() {
static ClassDocumentation<FIMassiveKinematics> documentation
("FIMassiveKinematics implements massless splittings "
"off a final-initial dipole.");
}
diff --git a/Shower/Dipole/Kinematics/FIMassiveKinematics.h b/Shower/Dipole/Kinematics/FIMassiveKinematics.h
--- a/Shower/Dipole/Kinematics/FIMassiveKinematics.h
+++ b/Shower/Dipole/Kinematics/FIMassiveKinematics.h
@@ -1,281 +1,273 @@
// -*- C++ -*-
//
// FILightKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_FILightKinematics_H
#define HERWIG_FILightKinematics_H
//
// This is the declaration of the FILightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll
*
* \brief FIMassiveKinematics implements massless splittings
* off a final-initial dipole.
*
*/
class FIMassiveKinematics: public DipoleSplittingKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
FIMassiveKinematics();
- /**
- * The destructor.
- */
- virtual ~FIMassiveKinematics();
- //@}
-
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy,
const DipoleSplittingInfo&,
const DipoleSplittingKernel&) const {
return {0.0,1.0};
}
/**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double, double,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
tPPtr emitter, tPPtr) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for massive
// dipoles, for now anyway.
assert(false);
return ZERO;
}
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for massive
// dipoles, for now anyway.
assert(false);
return ZERO;
}
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel&) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& dIndex,
const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline double rootOfKallen (T a, T b, T c) const {
double sres=a*a + b*b + c*c - 2.*( a*b+a*c+b*c );
return sres>0.?sqrt( sres ):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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<FIMassiveKinematics> initFIMassiveKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
FIMassiveKinematics & operator=(const FIMassiveKinematics &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of FIMassiveKinematics. */
template <>
struct BaseClassTrait<Herwig::FIMassiveKinematics,1> {
/** Typedef of the first base class of FIMassiveKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the FIMassiveKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::FIMassiveKinematics>
: public ClassTraitsBase<Herwig::FIMassiveKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::FIMassiveKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* FIMassiveKinematics is implemented. It may also include several, space-separated,
* libraries if the class FIMassiveKinematics 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_FIMassiveKinematics_H */
diff --git a/Shower/Dipole/Kinematics/IFLightKinematics.cc b/Shower/Dipole/Kinematics/IFLightKinematics.cc
--- a/Shower/Dipole/Kinematics/IFLightKinematics.cc
+++ b/Shower/Dipole/Kinematics/IFLightKinematics.cc
@@ -1,255 +1,253 @@
// -*- C++ -*-
//
// IFLightKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 IFLightKinematics class.
//
#include "IFLightKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
using namespace Herwig;
IFLightKinematics::IFLightKinematics()
: DipoleSplittingKinematics(), theCollinearScheme(true) {}
-IFLightKinematics::~IFLightKinematics() {}
-
IBPtr IFLightKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IFLightKinematics::fullclone() const {
return new_ptr(*this);
}
Energy IFLightKinematics::ptMax(Energy dScale,
double emX, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return dScale * sqrt((1.-emX)/emX) /2.;
}
Energy IFLightKinematics::QMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
assert(false && "add this");
return 0.0*GeV;
}
Energy IFLightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale*sqrt(1.-z);
}
Energy IFLightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale/sqrt(1.-z);
}
pair<double,double> IFLightKinematics::zBoundaries(Energy pt,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel&) const {
double x = dInfo.emitterX();
Energy hard=dInfo.hardPt();
if(openZBoundaries()==1)hard=dInfo.scale() * sqrt((1.-x)/x) /2.;
if(openZBoundaries()==2)hard=dInfo.scale() * min(1.,sqrt((1.-x)/x) /2.);
if(hard<pt)return {0.5*(1.+x),0.5*(1.+x)};
double s = sqrt(1.-sqr(pt/hard));
return {0.5*(1.+x-(1.-x)*s),0.5*(1.+x+(1.-x)*s)};
}
bool IFLightKinematics::generateSplitting(double kappa, double xi, double rphi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel& split) {
if ( info.emitterX() < xMin() ) {
jacobian(0.0);
return false;
}
double weight = 1.0;
Energy pt = generatePt(kappa,info.scale(),
info.emitterX(),info.spectatorX(),
info.index(),split,
weight);
if ( pt < IRCutoff() || pt > info.hardPt() ) {
jacobian(0.0);
return false;
}
double z = 0.0;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emitterData()->id() == ParticleID::g ) {
z = generateZ(xi,pt,OneOverZOneMinusZ,
info,split,weight);
} else {
z = generateZ(xi,pt,OneOverZ,
info,split,weight);
}
}
if ( info.index().emitterData()->id() != ParticleID::g ) {
if ( info.emitterData()->id() != ParticleID::g ) {
z = generateZ(xi,pt,OneOverOneMinusZ,
info,split,weight);
} else {
z = generateZ(xi,pt,FlatZ,
info,split,weight);
}
}
if ( weight == 0. && z == -1. ) {
jacobian(0.0);
return false;
}
double ratio = sqr(pt/info.scale());
double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
if ( rho < 0.0 ) {
jacobian(0.0);
return false;
}
double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
double u = 0.5*((1.-z+ratio)/(1.-z))*(1.-sqrt(rho));
if ( x < info.emitterX() || x > 1. ||
u < 0. || u > 1. ) {
jacobian(0.0);
return false;
}
double phi = 2.*Constants::pi*rphi;
jacobian(weight*(1./(u+x-2.*u*x)));
lastPt(pt);
lastZ(z);
lastPhi(phi);
lastEmitterZ(x);
if ( theMCCheck )
theMCCheck->book(info.emitterX(),1.,info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
void IFLightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
Energy pt = dInfo.lastPt();
double z = dInfo.lastZ();
double ratio = sqr(pt)/(2.*pEmitter*pSpectator);
double rho = 1. - 4.*ratio*z*(1.-z)/sqr(1.-z+ratio);
double x = 0.5*((1.-z+ratio)/ratio)*(1.-sqrt(rho));
double u = 0.5*((1.-z+ratio)/(1.-z))*(1.-sqrt(rho));
Lorentz5Momentum kt =
getKt(pEmitter, pSpectator, pt, dInfo.lastPhi(), true);
// Initialise the momenta
Lorentz5Momentum em;
Lorentz5Momentum emm;
Lorentz5Momentum spe;
if ( !theCollinearScheme &&
x > u && (1.-x)/(x-u) < 1. ) {
assert(false);
em = ((1.-u)/(x-u))*pEmitter + ((u/x)*(1.-x)/(x-u))*pSpectator - kt/(x-u);
emm = ((1.-x)/(x-u))*pEmitter + ((u/x)*(1.-u)/(x-u))*pSpectator - kt/(x-u);
spe = (1.-u/x)*pSpectator;
} else {
em = (1./x)*pEmitter;
emm = ((1.-x)*(1.-u)/x)*pEmitter + u*pSpectator + kt;
spe = ((1.-x)*u/x)*pEmitter + (1.-u)*pSpectator - kt;
}
em.setMass(ZERO);
em.rescaleEnergy();
emm.setMass(ZERO);
emm.rescaleEnergy();
spe.setMass(ZERO);
spe.rescaleEnergy();
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFLightKinematics::persistentOutput(PersistentOStream &) const {
//os << theCollinearScheme;
}
void IFLightKinematics::persistentInput(PersistentIStream &, int) {
//is >> theCollinearScheme;
}
ClassDescription<IFLightKinematics> IFLightKinematics::initIFLightKinematics;
// Definition of the static class description member.
void IFLightKinematics::Init() {
static ClassDocumentation<IFLightKinematics> documentation
("IFLightKinematics implements massless splittings "
"off a initial-final dipole.");
/*
static Switch<IFLightKinematics,bool> interfaceCollinearScheme
("CollinearScheme",
"[experimental] Switch on or off the collinear scheme",
&IFLightKinematics::theCollinearScheme, false, false, false);
static SwitchOption interfaceCollinearSchemeYes
(interfaceCollinearScheme,
"Yes",
"Switch on the collinear scheme.",
true);
static SwitchOption interfaceCollinearSchemeNo
(interfaceCollinearScheme,
"No",
"Switch off the collinear scheme",
false);
interfaceCollinearScheme.rank(-1);
*/
}
diff --git a/Shower/Dipole/Kinematics/IFLightKinematics.h b/Shower/Dipole/Kinematics/IFLightKinematics.h
--- a/Shower/Dipole/Kinematics/IFLightKinematics.h
+++ b/Shower/Dipole/Kinematics/IFLightKinematics.h
@@ -1,209 +1,201 @@
// -*- C++ -*-
//
// IFLightKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IFLightKinematics_H
#define HERWIG_IFLightKinematics_H
//
// This is the declaration of the IFLightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IFLightKinematics implements massless splittings
* off an initial-final dipole.
*
* @see \ref IFLightKinematicsInterfaces "The interfaces"
* defined for IFLightKinematics.
*/
class IFLightKinematics: public DipoleSplittingKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFLightKinematics();
- /**
- * The destructor.
- */
- virtual ~IFLightKinematics();
- //@}
-
public:
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex&,
const DipoleSplittingKernel&) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel&) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy pt,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& dIndex,
const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFLightKinematics> initIFLightKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFLightKinematics & operator=(const IFLightKinematics &) = delete;
private:
/**
* Wether or not to choose the `collinear' scheme
*/
bool theCollinearScheme;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFLightKinematics. */
template <>
struct BaseClassTrait<Herwig::IFLightKinematics,1> {
/** Typedef of the first base class of IFLightKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFLightKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFLightKinematics>
: public ClassTraitsBase<Herwig::IFLightKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFLightKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* IFLightKinematics is implemented. It may also include several, space-separated,
* libraries if the class IFLightKinematics 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_IFLightKinematics_H */
diff --git a/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.cc b/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.cc
--- a/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.cc
+++ b/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.cc
@@ -1,392 +1,390 @@
// -*- C++ -*-
//
// IFMassiveDecayKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 IFMassiveDecayKinematics class.
//
#include "IFMassiveDecayKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
#include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
using namespace Herwig;
IFMassiveDecayKinematics::IFMassiveDecayKinematics()
: DipoleSplittingKinematics() {}
-IFMassiveDecayKinematics::~IFMassiveDecayKinematics() {}
-
IBPtr IFMassiveDecayKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IFMassiveDecayKinematics::fullclone() const {
return new_ptr(*this);
}
pair<double,double> IFMassiveDecayKinematics::kappaSupport(const DipoleSplittingInfo&) const {
return {0.0,1.0};
}
pair<double,double> IFMassiveDecayKinematics::xiSupport(const DipoleSplittingInfo& split) const {
double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
if ( split.index().emitterData()->id() == ParticleID::g ) {
if ( split.emissionData()->id() != ParticleID::g ){
return {0.5*(1.-c),0.5*(1.+c)};}
double b = log((1.+c)/(1.-c));
return {-b,b};
}
return {-log(0.5*(1.+c)),-log(0.5*(1.-c))};
}
Energy IFMassiveDecayKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum&) const {
return pEmitter.m();
}
Energy IFMassiveDecayKinematics::recoilMassKin(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const {
Lorentz5Momentum pk = pEmitter - pSpectator;
double pkmass = pk.m();
return pkmass;
}
Energy IFMassiveDecayKinematics::ptMax(Energy dScale,
double, double,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const {
DipoleIndex ind = dInfo.index();
double mui = split.spectator(ind)->mass() / dScale;
double mu = split.emission(ind)->mass() / dScale;
// Mass of recoil system
// Use abs() due to generation of negative
// recoilMass during sampling.
double muj = abs(dInfo.recoilMass() / dScale);
double mui2 = sqr( mui ), mu2 = sqr( mu );
return rootOfKallen( mui2, mu2, sqr(1.-muj) ) / ( 2.-2.*muj ) * dScale;
}
Energy IFMassiveDecayKinematics::QMax(Energy dScale,
double, double,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel&) const {
assert(false && "implementation missing");
// Mass of recoil system
double Muj = abs(dInfo.recoilMass() / dScale);
return dScale * ( 1.-2.*Muj+sqr(Muj) );
}
Energy IFMassiveDecayKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
// from Martin's thesis
double zPrime = split.lastSplittingParameters()[0];
Energy mi = split.spectatorData()->mass();
Energy m = split.emissionData()->mass();
Energy2 pt2 = zPrime*(1.-zPrime)*sqr(scale) - (1-zPrime)*sqr(mi) - zPrime*sqr(m);
assert(pt2 >= ZERO);
return sqrt(pt2);
}
Energy IFMassiveDecayKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
// from Martin's thesis
double zPrime = split.lastSplittingParameters()[0];
Energy mi = split.spectatorData()->mass();
Energy m = split.emissionData()->mass();
Energy2 Q2 = (sqr(scale) + (1-zPrime)*sqr(mi) + zPrime*sqr(m))/(zPrime*(1.-zPrime));
return sqrt(Q2);
}
double IFMassiveDecayKinematics::ptToRandom(Energy pt, Energy,
double,double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
}
bool IFMassiveDecayKinematics::generateSplitting(double kappa, double xi, double rphi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel&) {
// Construct mass squared variables
Energy2 mi2 = sqr( info.spectatorData()->mass() );
Energy2 mj2 = sqr( info.emissionData()->mass() );
// Specific to the IFDecay kinematics
Energy2 mij2 = mi2;
Energy2 mk2 = sqr( info.recoilMass() );
Energy2 Qijk = sqr( info.scale());
// To solve issue with scale during presampling
// need to enforce that Qijk-mij2-mk2 = 2*pij.pk > 0,
// so combine checks by comparing against square root.
if ( Qijk-mij2-mk2 < sqrt(4.*mij2*mk2) ) {
jacobian(0.0);
return false;
}
Energy2 sijk = 0.5*( Qijk - mij2 - mk2 + sqrt( sqr(Qijk-mij2-mk2) - 4.*mij2*mk2 ) );
// Calculate pt
Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
Energy2 pt2 = sqr(pt);
if ( pt > info.hardPt() || pt < IRCutoff() ) {
jacobian(0.0);
return false;
}
// Generate zPrime (i.e. the new definition of z specific to massive FF and decays)
double zPrime;
// TODO: This may need to change along with the emitter and spectator usage, if IFDecays are implemented again
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
zPrime = xi;
}
else {
zPrime = exp(xi)/(1.+exp(xi));
}
}
else {
zPrime = 1.-exp(-xi);
}
// scaled masses *** TODO: rewrite above in terms of mu to avoid this calculation ***, and mix up of notation
double mui2 = mi2 / Qijk;
double mu2 = mj2 / Qijk;
double muj2 = mk2 / Qijk;
double Mui2 = mui2;
double Muj2 = muj2;
// Check limit on pt
Energy ptmax1 = rootOfKallen( mui2, mu2, sqr(1.-sqrt(muj2)) ) /
( 2.-2.*sqrt(muj2) ) * info.scale();
Energy auxHardPt = ptmax1 > info.hardPt() ? info.hardPt() : ptmax1;
// 24/05/2015: Moved this check from the zPrime limit checks
if ( pt > auxHardPt ){
jacobian(0.0);
return false;
}
// 2011-11-09
//assert(ptmax1>info.hardPt());
// 24/05/2015:
// The simple >= assert above is triggered
// during sampling due to precision.
// Have added a tolerance to deal with this.
assert( abs(ptmax1 - info.hardPt()) <= 1e-8 || ptmax1>=info.hardPt() );
// new: 2011-08-31
// 2011-11-08: this does happen
if( sqrt(mui2)+sqrt(mu2)+sqrt(muj2) > 1. ){
jacobian(0.0);
return false;
}
// I have derived and checked the equations for zp1 and zm1, these apply to zPrime!!!
// phasespace constraint to incorporate ptMax
double zp1 = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) +
rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) *
sqrt( 1.-sqr(pt/auxHardPt) ) ) /
( 2.*sqr(1.-sqrt(muj2)) );
double zm1 = ( 1.+mui2-mu2+muj2-2.*sqrt(muj2) -
rootOfKallen(mui2,mu2,sqr(1-sqrt(muj2))) *
sqrt( 1.-sqr(pt/auxHardPt) ) ) /
( 2.*sqr(1.-sqrt(muj2)) );
if ( zPrime > zp1 || zPrime < zm1 ) {
jacobian(0.0);
return false;
}
// Calculate A:=xij*w
double A = (1./(sijk*zPrime*(1.-zPrime))) * ( pt2 + zPrime*mj2 + (1.-zPrime)*mi2 - zPrime*(1.-zPrime)*mij2 );
// Calculate y from A (can also write explicitly in terms of qt, zPrime and masses however we need A anyway)
Energy2 sbar = Qijk - mi2 - mj2 - mk2;
double y = (1./sbar) * (A*sijk + mij2 - mi2 - mj2);
// kinematic phasespace boundaries for y
// same as in Dittmaier hep-ph/9904440v2 (equivalent to CS)
double bar = 1.-mui2-mu2-muj2;
double ym = 2.*sqrt(mui2)*sqrt(mu2)/bar;
double yp = 1. - 2.*sqrt(muj2)*(1.-sqrt(muj2))/bar;
if ( y < ym || y > yp ) {
jacobian(0.0);
return false;
}
// Calculate xk and xij
double lambdaK = 1. + (mk2/sijk);
double lambdaIJ = 1. + (mij2/sijk);
double xk = (1./(2.*lambdaK)) * ( (lambdaK + (mk2/sijk)*lambdaIJ - A) + sqrt( sqr(lambdaK + (mk2/sijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*mk2/sijk) );
double xij = 1. - ( (mk2/sijk) * (1.-xk) / xk );
// Transform to standard z definition as used in the kernels (i.e. that used in CS and standard sudakov parametrisations)
double z =
( (zPrime*xij*xk*sijk/2.) + (mk2/ ( 2.*xk*xij*sijk*zPrime))*(pt2 + mi2) ) /
( (xij*xk*sijk/2.) + (mk2*mij2/(2.*xk*xij*sijk)) + (mk2/(2.*xk*xij))*A );
// I think these apply to z but need to double check
double zm = ( (2.*mui2+bar*y)*(1.-y) - sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
( 2.*(1.-y)*(mui2+mu2+bar*y) );
double zp = ( (2.*mui2+bar*y)*(1.-y) + sqrt(y*y-ym*ym)*sqrt(sqr(2.*muj2+bar-bar*y)-4.*muj2) ) /
( 2.*(1.-y)*(mui2+mu2+bar*y) );
if ( z < zm || z > zp ) {
jacobian(0.0);
return false;
}
double phi = 2.*Constants::pi*rphi;
// TODO: This may need changing due to different definitions of z
double mapZJacobian;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emissionData()->id() != ParticleID::g ) {
mapZJacobian = 1.;
}
else {
mapZJacobian = z*(1.-z);
}
}
else {
mapZJacobian = 1.-z;
}
// TODO: May need a redefinition due to different definitions of z
jacobian( 2. * mapZJacobian * (1.-y) *
log(0.5 * generator()->maximumCMEnergy()/IRCutoff()) *
bar / rootOfKallen(1.,Mui2,Muj2) );
// Record the physical variables, as used by the CS kernel definitions
lastPt(pt);
lastZ(z);
lastPhi(phi);
// Record zPrime for use in kinematics generation and kernel evaluation
splittingParameters().clear();
splittingParameters().push_back(zPrime);
if ( theMCCheck ) {
theMCCheck->book(1.,1.,info.scale(),info.hardPt(),pt,z,jacobian());
}
return true;
}
// Check use of const
void IFMassiveDecayKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
// There is no plan to implement IF-type decays,
// therefore these kinematics have not been kept up-to-date,
// have not had any bug fixes and have not been kept up-to-date
// with other developments since their creation.
assert(false && "The should be no initial-final type decay dipoles being showered, something is wrong.");
// The only value stored in dInfo.lastSplittingParameters() should be zPrime
assert(dInfo.lastSplittingParameters().size() == 1 );
double zPrime = dInfo.lastSplittingParameters()[0];
Energy pt = dInfo.lastPt();
Energy2 pt2 = sqr(pt);
// Momentum of the recoil system
Lorentz5Momentum pk = pEmitter-pSpectator;
Lorentz5Momentum pij = pSpectator;
// Masses - Currently not using the mu-ratio formalism and using a different notation to Simon
Energy2 mi2 = sqr( dInfo.spectatorData()->mass() );
Energy2 mj2 = sqr( dInfo.emissionData()->mass() );
Energy2 mij2 = mi2;
Energy2 mk2 = sqr(dInfo.recoilMass());
Energy2 Qijk = sqr(dInfo.scale());
Energy2 sijk = 0.5*( Qijk - mij2 - mk2 + sqrt( sqr(Qijk-mij2-mk2) - 4.*mij2*mk2 ) );
Energy4 sijk2 = sqr(sijk);
// Calculate A:=xij*w
double A = (1./(sijk*zPrime*(1.-zPrime))) * ( pt2 + zPrime*mj2 + (1.-zPrime)*mi2 - zPrime*(1.-zPrime)*mij2 );
// Calculate xk and xij
double lambdaK = 1. + (mk2/sijk);
double lambdaIJ = 1. + (mij2/sijk);
double xk = (1./(2.*lambdaK)) * ( (lambdaK + (mk2/sijk)*lambdaIJ - A) + sqrt( sqr(lambdaK + (mk2/sijk)*lambdaIJ - A) - 4.*lambdaK*lambdaIJ*mk2/sijk) );
double xij = 1. - ( (mk2/sijk) * (1.-xk) / xk );
// Construct reference momenta nk, nij, nt
Lorentz5Momentum nij = ( sijk2 / (sijk2-mij2*mk2) ) * (pij - (mij2/sijk)*pk);
Lorentz5Momentum nk = ( sijk2 / (sijk2-mij2*mk2) ) * (pk - (mk2/sijk)*pij);
// Following notation in notes, qt = sqrt(wt)*nt
Lorentz5Momentum qt = getKt(nij, nk, pt, dInfo.lastPhi());
// Construct qij, qk, qi and qj
Lorentz5Momentum qij = xij*nij + (mij2/(xij*sijk))*nk;
Lorentz5Momentum qk = xk*nk + (mk2/(xk*sijk))*nij;
// No need to actually calculate nt and wt:
Lorentz5Momentum qi = zPrime*qij + ((pt2 + mi2 - zPrime*zPrime*mij2)/(xij*sijk*zPrime))*nk + qt;
Lorentz5Momentum qj = (1.-zPrime)*qij + ((pt2 + mj2 - sqr(1.-zPrime)*mij2)/(xij*sijk*(1.-zPrime)))*nk - qt;
// book
spectatorMomentum(qi);
emissionMomentum(qj);
emitterMomentum(pEmitter);
//recoilMomentum is not currently used
//recoilMomentum(pk);
splitRecoilMomentum(qk);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFMassiveDecayKinematics::persistentOutput(PersistentOStream & ) const {
}
void IFMassiveDecayKinematics::persistentInput(PersistentIStream & , int) {
}
ClassDescription<IFMassiveDecayKinematics> IFMassiveDecayKinematics::initIFMassiveDecayKinematics;
// Definition of the static class description member.
void IFMassiveDecayKinematics::Init() {
static ClassDocumentation<IFMassiveDecayKinematics> documentation
("IFMassiveDecayKinematics implements implements massive splittings "
"off an initial-final decay dipole.");
}
diff --git a/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.h b/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.h
--- a/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.h
+++ b/Shower/Dipole/Kinematics/IFMassiveDecayKinematics.h
@@ -1,297 +1,289 @@
// -*- C++ -*-
//
// IFMassiveDecayKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IFMassiveDecayKinematics_H
#define HERWIG_IFMassiveDecayKinematics_H
//
// This is the declaration of the IFMassiveDecayKinematics class.
//
#include "DipoleSplittingKinematics.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Utilities/UtilityBase.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Stephen Webster
*
* \brief IFMassiveDecayKinematics implements massive splittings
* off an initial-final decay dipole.
*
*/
class IFMassiveDecayKinematics: public DipoleSplittingKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFMassiveDecayKinematics();
- /**
- * The destructor.
- */
- virtual ~IFMassiveDecayKinematics();
- //@}
-
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy,
const DipoleSplittingInfo&,
const DipoleSplittingKernel&) const {
return {0.0,1.0};
}
/**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the mass of the system absorbing
* the recoil in the dipole splitting.
* This is only used in decay dipoles.
*/
virtual Energy recoilMassKin(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for the decays.
assert(false);
return 0.0;
}
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for the decays.
assert(false);
return 0.0;
}
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel& split);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
/*
* Return true if this splitting is of a dipole which contains
* a decayed parton and requires the remnant to absorb the recoil.
*/
virtual bool isDecay() const { return true; }
/**
* Perform the recoil in the case of a decayed parton
*/
virtual void decayRecoil ( PList& recoilSystem ) {
PList::iterator beginRecoil = recoilSystem.begin();
PList::iterator endRecoil = recoilSystem.end();
const ThreeVector<double> transformMom = splitRecoilMomentum().vect();
ThePEG::UtilityBase::setMomentum(beginRecoil, endRecoil, transformMom );
}
public:
/**
* Triangular / Kallen function
*/
template <class T>
inline double rootOfKallen (T a, T b, T c) const {
double sres=a*a + b*b + c*c - 2.*( a*b+a*c+b*c );
return sres>0.?sqrt( sres ):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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFMassiveDecayKinematics> initIFMassiveDecayKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFMassiveDecayKinematics & operator=(const IFMassiveDecayKinematics &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFMassiveDecayKinematics. */
template <>
struct BaseClassTrait<Herwig::IFMassiveDecayKinematics,1> {
/** Typedef of the first base class of IFMassiveDecayKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFMassiveDecayKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFMassiveDecayKinematics>
: public ClassTraitsBase<Herwig::IFMassiveDecayKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFMassiveDecayKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* IFMassiveDecayKinematics is implemented. It may also include several, space-separated,
* libraries if the class IFMassiveDecayKinematics 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_IFMassiveDecayKinematics_H */
diff --git a/Shower/Dipole/Kinematics/IFMassiveKinematics.cc b/Shower/Dipole/Kinematics/IFMassiveKinematics.cc
--- a/Shower/Dipole/Kinematics/IFMassiveKinematics.cc
+++ b/Shower/Dipole/Kinematics/IFMassiveKinematics.cc
@@ -1,373 +1,371 @@
// -*- C++ -*-
//
// IFMassiveKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 IFMassiveKinematics class.
//
#include "IFMassiveKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
#include "Herwig/Shower/Dipole/Kernels/DipoleSplittingKernel.h"
using namespace Herwig;
IFMassiveKinematics::IFMassiveKinematics()
: DipoleSplittingKinematics(), theCollinearScheme(true) {}
-IFMassiveKinematics::~IFMassiveKinematics() {}
-
IBPtr IFMassiveKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IFMassiveKinematics::fullclone() const {
return new_ptr(*this);
}
pair<double,double> IFMassiveKinematics::kappaSupport(const DipoleSplittingInfo&) const {
return {0.0,1.0};
}
pair<double,double> IFMassiveKinematics::xiSupport(const DipoleSplittingInfo& split) const {
double c = sqrt(1.-4.*sqr(IRCutoff()/generator()->maximumCMEnergy()));
if ( split.index().emitterData()->id() == ParticleID::g ) {
if ( split.emitterData()->id() == ParticleID::g ) {
double b = log((1.+c)/(1.-c));
return {-b,b};
} else {
return {log(0.5*(1.-c)),log(0.5*(1.+c))};
}
}
if ( split.index().emitterData()->id() != ParticleID::g &&
split.emitterData()->id() != ParticleID::g ) {
return {-log(0.5*(1.+c)),-log(0.5*(1.-c))};
}
return {0.5*(1.-c),0.5*(1.+c)};
}
// sbar
Energy IFMassiveKinematics::dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const {
return sqrt(2.*(pEmitter*pSpectator));
}
Energy IFMassiveKinematics::ptMax(Energy dScale,
double emX, double,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel&) const {
Energy2 A = sqr(dScale) * (1.-emX)/emX;
Energy2 mk2 = sqr(dInfo.spectatorMass());
Energy ptMax = 0.5*A/sqrt(mk2+A);
return ptMax;
}
Energy IFMassiveKinematics::ptMax(Energy dScale,
double emX, double,
const DipoleIndex&,
const DipoleSplittingKernel&,
tPPtr, tPPtr spectator) const {
Energy2 A = sqr(dScale) * (1.-emX)/emX;
Energy2 mk2 = sqr(spectator->mass());
Energy ptMax = 0.5*A/sqrt(mk2+A);
return ptMax;
}
Energy IFMassiveKinematics::QMax(Energy,
double, double,
const DipoleSplittingInfo&,
const DipoleSplittingKernel&) const {
assert(false && "add this");
return 0.0*GeV;
}
Energy IFMassiveKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale*sqrt(1.-z);
}
Energy IFMassiveKinematics::QFromPt(Energy pt, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return pt/sqrt(1.-z);
}
double IFMassiveKinematics::ptToRandom(Energy pt, Energy,
double,double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
return log(pt/IRCutoff()) / log(0.5 * generator()->maximumCMEnergy()/IRCutoff());
}
bool IFMassiveKinematics::generateSplitting(double kappa, double xi, double rphi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel&) {
// Check emitter x against xmin
if ( info.emitterX() < xMin() ) {
jacobian(0.0);
return false;
}
// Generate pt and check it against max allowed
Energy pt = IRCutoff() * pow(0.5 * generator()->maximumCMEnergy()/IRCutoff(),kappa);
if ( pt < IRCutoff() || pt > info.hardPt() ) {
jacobian(0.0);
return false;
}
// Compute scales required
Energy2 pt2 = sqr(pt);
Energy2 saj = sqr(info.scale());
Energy2 mk2 = sqr(info.spectatorMass());
// Generate z
double z = 0.;
double mapZJacobian = 0.;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emitterData()->id() == ParticleID::g ) {
z = exp(xi)/(1.+exp(xi));
mapZJacobian = z*(1.-z);
} else {
z = exp(xi);
mapZJacobian = z;
}
}
if ( info.index().emitterData()->id() != ParticleID::g ) {
if ( info.emitterData()->id() != ParticleID::g ) {
z = 1.-exp(-xi);
mapZJacobian = 1.-z;
} else {
z = xi;
mapZJacobian = 1.;
}
}
// Check limits on z
double xe = info.emitterX();
Energy hard = info.hardPt();
if(openZBoundaries()==1){
Energy2 A = saj*(1.-xe)/xe;
hard = 0.5*A/sqrt(mk2+A);
}
if(openZBoundaries()==2){
Energy2 A = saj*min(1.,(1.-xe)/xe);
hard= 0.5*A/sqrt(mk2+A);
assert(pt2<=sqr(hard));
}
double ptRatio = sqrt(1. - pt2/sqr(hard) );
double zp = 0.5*(1.+xe + (1.-xe)*ptRatio);
double zm = 0.5*(1.+xe - (1.-xe)*ptRatio);
if ( z < zm || z > zp ) {
jacobian(0.0);
return false;
}
// Calculate x and u in terms of z and pt
double r = pt2/saj;
double muk2 = mk2/saj;
double rho = 1. - 4.*r*(1.-muk2)*z*(1.-z)/sqr(1.-z+r);
if ( rho < 0.0 ) {
// This has never happened
jacobian(0.0);
return false;
}
double x = 0.5*((1.-z+r)/(r*(1.-muk2))) * (1. - sqrt(rho));
double u = x*r / (1.-z);
// Check limits on x and u
// Following Catani-Seymour paper
double muk2CS = x*muk2;
double up = (1.-x) / ( 1.-x + muk2CS );
if ( x < xe || x > 1. ||
u < 0. || u > up ) {
jacobian(0.0);
return false;
}
// Compute the Jacobian
double jac = 1./(u + x - 2.*u*x*(1.-muk2));
jacobian( jac * mapZJacobian * 2. * log(0.5 * generator()->maximumCMEnergy()/IRCutoff()));
// Log results
double phi = 2.*Constants::pi*rphi;
lastPt(pt);
lastZ(z);
lastPhi(phi);
lastEmitterZ(x);
if ( theMCCheck )
theMCCheck->book(info.emitterX(),1.,info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
void IFMassiveKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
// Initialise the momenta
Lorentz5Momentum em;
Lorentz5Momentum emm;
Lorentz5Momentum spe;
if (!theCollinearScheme) {
assert(false);
Energy2 sbar = 2.*pEmitter*pSpectator;
Energy pt = dInfo.lastPt();
double ratio = pt*pt/sbar;
double z = dInfo.lastZ();
double x = (z*(1.-z)-ratio)/(1.-z-ratio);
double u = ratio / (1.-z);
pt = sqrt(sbar*u*(1.-u)*(1.-x));
Energy magKt =
sqrt(sbar*u*(1.-u)*(1.-x)/x - sqr(u*dInfo.spectatorMass()));
Lorentz5Momentum kt =
getKt (pSpectator, pEmitter, magKt, dInfo.lastPhi(),true);
Energy2 mj2 = sqr(dInfo.spectatorMass());
double alpha = 1. - 2.*mj2/sbar;
if ( x > u && (1.-x)/(x-u) < 1. ) {
double fkt = sqrt(sqr(x-u)+4.*x*u*mj2/sbar);
// em =
// ((1.-u)/(x-u))*pEmitter + ((u/x)*(1.-x)/(x-u))*pSpectator - kt/(x-u);
Energy2 fa = (sbar*(x+u-2.*x*z)+2.*mj2*x*u) / sqrt(sqr(x-u)+4.*x*u*mj2/sbar);
double a = (-sbar+fa) / (2.*x*(sbar-mj2));
double ap = (sbar+alpha*fa) / (2.*x*(sbar-mj2));
em = ap*pEmitter + a*pSpectator - fkt*kt;
// emm =
// ((1.-x)/(x-u))*pEmitter + ((u/x)*(1.-u)/(x-u))*pSpectator - kt/(x-u);
Energy2 fb = abs(sbar*(u*(1.-u)-x*(1.-x))+2.*mj2*x*u) / sqrt(sqr(x-u)+4.*x*u*mj2/sbar);
double b = (-sbar*(1.-x-u)+fb) / (2.*x*(sbar-mj2));
double bp = (sbar*(1.-x-u)+alpha*fb) / (2.*x*(sbar-mj2));
emm = bp*pEmitter + b*pSpectator + fkt*kt;
// spe =
// (1.-u/x)*pSpectator;
Energy2 fc = sqrt(sqr(sbar*(x-u))+4.*sbar*mj2*x*u);
double c = (sbar*(x-u)-2.*x*mj2+fc) / (2.*x*(sbar-mj2));
double cp = (-sbar*(x-u)+2.*x*mj2+alpha*fc) / (2.*x*(sbar-mj2));
spe = cp*pEmitter + c*pSpectator;
}
}
else {
// Get z, pt and the relevant scales
double z = dInfo.lastZ();
Energy pt = dInfo.lastPt();
Energy2 pt2 = sqr(pt);
Energy2 saj = 2.*pEmitter*pSpectator;
double muk2 = sqr(dInfo.spectatorMass())/saj;
double r = pt2/saj;
// Calculate x and u
double rho = 1. - 4.*r*(1.-muk2)*z*(1.-z)/sqr(1.-z+r);
double x = 0.5*((1.-z+r)/(r*(1.-muk2))) * (1. - sqrt(rho));
double u = x*r / (1.-z);
// Generate kt
Lorentz5Momentum kt = getKt(pEmitter, pSpectator, pt, dInfo.lastPhi(), true);
// Set the momenta
em = (1./x)*pEmitter;
emm = ((1.-x)*(1.-u)/x - 2.*u*muk2)*pEmitter + u*pSpectator + kt;
spe = ((1.-x)*u/x + 2.*u*muk2)*pEmitter + (1.-u)*pSpectator - kt;
}
em.setMass(ZERO);
em.rescaleEnergy();
emm.setMass(ZERO);
emm.rescaleEnergy();
spe.setMass(dInfo.spectatorMass());
spe.rescaleEnergy();
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IFMassiveKinematics::persistentOutput(PersistentOStream &) const {
//os << theCollinearScheme;
}
void IFMassiveKinematics::persistentInput(PersistentIStream &, int) {
//is >> theCollinearScheme;
}
ClassDescription<IFMassiveKinematics> IFMassiveKinematics::initIFMassiveKinematics;
// Definition of the static class description member.
void IFMassiveKinematics::Init() {
static ClassDocumentation<IFMassiveKinematics> documentation
("IFMassiveKinematics implements massless splittings "
"off a initial-final dipole.");
/*
static Switch<IFMassiveKinematics,bool> interfaceCollinearScheme
("CollinearScheme",
"[experimental] Switch on or off the collinear scheme",
&IFMassiveKinematics::theCollinearScheme, false, false, false);
static SwitchOption interfaceCollinearSchemeYes
(interfaceCollinearScheme,
"Yes",
"Switch on the collinear scheme.",
true);
static SwitchOption interfaceCollinearSchemeNo
(interfaceCollinearScheme,
"No",
"Switch off the collinear scheme",
false);
interfaceCollinearScheme.rank(-1);
*/
}
diff --git a/Shower/Dipole/Kinematics/IFMassiveKinematics.h b/Shower/Dipole/Kinematics/IFMassiveKinematics.h
--- a/Shower/Dipole/Kinematics/IFMassiveKinematics.h
+++ b/Shower/Dipole/Kinematics/IFMassiveKinematics.h
@@ -1,279 +1,271 @@
// -*- C++ -*-
//
// IFLightKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IFLightKinematics_H
#define HERWIG_IFLightKinematics_H
//
// This is the declaration of the IFLightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Martin Stoll
*
* \brief IFMassiveKinematics implements massless splittings
* off an initial-final dipole.
*
* @see \ref IFMassiveKinematicsInterfaces "The interfaces"
* defined for IFMassiveKinematics.
*/
class IFMassiveKinematics: public DipoleSplittingKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IFMassiveKinematics();
- /**
- * The destructor.
- */
- virtual ~IFMassiveKinematics();
- //@}
-
public:
/**
* Return the boundaries in between the evolution
* variable random number is to be sampled; the lower
* cuoff is assumed to correspond to the infrared cutoff.
*/
virtual pair<double,double> kappaSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries in between the momentum
* fraction random number is to be sampled.
*/
virtual pair<double,double> xiSupport(const DipoleSplittingInfo& dIndex) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy,
const DipoleSplittingInfo&,
const DipoleSplittingKernel&) const {
return {0.0,1.0};
}
/**
* Return the dipole scale associated to the
* given pair of emitter and spectator. This
* should be the invariant mass or absolute value
* final/final or initial/initial and the absolute
* value of the momentum transfer for intial/final or
* final/initial dipoles.
*/
virtual Energy dipoleScale(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double, double,
const DipoleIndex& dIndex,
const DipoleSplittingKernel& split,
tPPtr emitter, tPPtr) const;
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for massive
// dipoles, for now anyway.
assert(false);
return ZERO;
}
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
// Only the DipoleSplittingInfo version should be used for massive
// dipoles, for now anyway.
assert(false);
return ZERO;
}
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the random number associated to
* the given pt.
*/
virtual double ptToRandom(Energy pt, Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel&) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& dIndex,
const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IFMassiveKinematics> initIFMassiveKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IFMassiveKinematics & operator=(const IFMassiveKinematics &) = delete;
private:
/**
* Wether or not to choose the `collinear' scheme
*/
bool theCollinearScheme;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IFMassiveKinematics. */
template <>
struct BaseClassTrait<Herwig::IFMassiveKinematics,1> {
/** Typedef of the first base class of IFMassiveKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IFMassiveKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IFMassiveKinematics>
: public ClassTraitsBase<Herwig::IFMassiveKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IFMassiveKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* IFMassiveKinematics is implemented. It may also include several, space-separated,
* libraries if the class IFMassiveKinematics 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_IFMassiveKinematics_H */
diff --git a/Shower/Dipole/Kinematics/IILightKinematics.cc b/Shower/Dipole/Kinematics/IILightKinematics.cc
--- a/Shower/Dipole/Kinematics/IILightKinematics.cc
+++ b/Shower/Dipole/Kinematics/IILightKinematics.cc
@@ -1,358 +1,356 @@
// -*- C++ -*-
//
// IILightKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 IILightKinematics class.
//
#include "IILightKinematics.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/Shower/Dipole/Base/DipoleSplittingInfo.h"
using namespace Herwig;
IILightKinematics::IILightKinematics()
: DipoleSplittingKinematics(), theCollinearScheme(true), didCollinear(false),
theTransformationCalculated(false) {}
//theTransformHardOnly(false) {}
-IILightKinematics::~IILightKinematics() {}
-
IBPtr IILightKinematics::clone() const {
return new_ptr(*this);
}
IBPtr IILightKinematics::fullclone() const {
return new_ptr(*this);
}
Energy IILightKinematics::ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
double tau =
!theCollinearScheme ? emX*specX : emX;
return (1.-tau) * dScale / (2.*sqrt(tau));
}
Energy IILightKinematics::QMax(Energy,
double, double,
const DipoleIndex&,
const DipoleSplittingKernel&) const {
assert(false && "add this");
return 0.0*GeV;
}
Energy IILightKinematics::PtFromQ(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale*sqrt(1.-z);
}
Energy IILightKinematics::QFromPt(Energy scale, const DipoleSplittingInfo& split) const {
double z = split.lastZ();
return scale/sqrt(1.-z);
}
pair<double,double> IILightKinematics::zBoundaries(Energy pt,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel&) const {
double x =
!theCollinearScheme ?
dInfo.emitterX()*dInfo.spectatorX() :
dInfo.emitterX();
Energy hard=dInfo.hardPt();
if(openZBoundaries()==1)hard=(1.-x) *dInfo.scale()/(2.*sqrt(x));
if(openZBoundaries()==2)hard=min(dInfo.scale(),(1.-x) *dInfo.scale()/(2.*sqrt(x)));
if(hard<pt)return {0.5*(1.+x),0.5*(1.+x)};
double s = sqrt(1.-sqr(pt/hard));
return {0.5*(1.+x-(1.-x)*s),0.5*(1.+x+(1.-x)*s)};
}
bool IILightKinematics::generateSplitting(double kappa, double xi, double rphi,
DipoleSplittingInfo& info,
const DipoleSplittingKernel& split) {
if ( info.emitterX() < xMin() ||
info.spectatorX() < xMin() ) {
jacobian(0.0);
return false;
}
double weight = 1.0;
Energy pt = generatePt(kappa,info.scale(),
info.emitterX(),info.spectatorX(),
info.index(),split,
weight);
if ( pt < IRCutoff() || pt > info.hardPt() ) {
jacobian(0.0);
return false;
}
double z = 0.0;
if ( info.index().emitterData()->id() == ParticleID::g ) {
if ( info.emitterData()->id() == ParticleID::g ) {
z = generateZ(xi,pt,OneOverZOneMinusZ,
info,split,weight);
} else {
z = generateZ(xi,pt,OneOverZ,
info,split,weight);
}
}
if ( info.index().emitterData()->id() != ParticleID::g ) {
if ( info.emitterData()->id() != ParticleID::g ) {
z = generateZ(xi,pt,OneOverOneMinusZ,
info,split,weight);
} else {
z = generateZ(xi,pt,FlatZ,
info,split,weight);
}
}
if ( weight == 0. && z == -1. ) {
jacobian(0.0);
return false;
}
double ratio = sqr(pt/info.scale());
double x = z*(1.-z)/(1.-z+ratio);
double v = ratio*z /(1.-z+ratio);
if ( x < 0. || x > 1. || v < 0. || v > 1.-x ) {
jacobian(0.0);
return false;
}
if ( !theCollinearScheme &&
(1.-v-x)/(v+x) < 1. ) {
if ( (x+v) < info.emitterX() ||
x/(x+v) < info.spectatorX() ) {
jacobian(0.0);
return false;
}
} else {
if ( x < info.emitterX() ) {
jacobian(0.0);
return false;
}
}
double phi = 2.*Constants::pi*rphi;
jacobian(weight*(1./z));
lastPt(pt);
lastZ(z);
lastPhi(phi);
if ( !theCollinearScheme &&
(1.-v-x)/(v+x) < 1. ) {
lastEmitterZ(x+v);
lastSpectatorZ(x/(x+v));
} else {
lastEmitterZ(x);
lastSpectatorZ(1.);
}
if ( theMCCheck )
theMCCheck->book(info.emitterX(),info.spectatorX(),info.scale(),info.hardPt(),pt,z,jacobian());
return true;
}
void IILightKinematics::generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo) {
Energy pt = dInfo.lastPt();
double z = dInfo.lastZ();
double ratio = sqr(pt)/(2.*pEmitter*pSpectator);
double x = z*(1.-z)/(1.-z+ratio);
double v = ratio*z /(1.-z+ratio);
Lorentz5Momentum kt =
getKt(pEmitter, pSpectator, pt, dInfo.lastPhi());
// Initialise the momenta
Lorentz5Momentum em;
Lorentz5Momentum emm;
Lorentz5Momentum spe;
if ( !theCollinearScheme &&
(1.-v-x)/(v+x) < 1. ) {
assert(false);
em = (1./(v+x))*pEmitter+(v*(1.-v-x)/(x*(x+v)))*pSpectator+kt/(x+v);
emm = ((1.-v-x)/(v+x))*pEmitter+(v/(x*(x+v)))*pSpectator+kt/(x+v);
spe = (1.+v/x)*pSpectator;
didCollinear = false;
} else {
em = (1./x)*pEmitter;
emm = ((1.-x-v)/x)*pEmitter+v*pSpectator+kt;
spe = pSpectator;
K = em + spe - emm;
K2 = K.m2();
Ktilde = pEmitter + pSpectator;
KplusKtilde = K + Ktilde;
KplusKtilde2 = KplusKtilde.m2();
didCollinear = true;
// Set indicator that the transformation,
// required for spin correlations, hasn't
// been calculated.
theTransformationCalculated = false;
}
em.setMass(ZERO);
em.rescaleEnergy();
emm.setMass(ZERO);
emm.rescaleEnergy();
spe.setMass(ZERO);
spe.rescaleEnergy();
emitterMomentum(em);
emissionMomentum(emm);
spectatorMomentum(spe);
}
void IILightKinematics::setTransformation () {
// Construct transformation for spin correlations
// Clear the rotation
theRecoilTransformation = LorentzRotation();
// Construct boost part
Energy KplusKtildeT = KplusKtilde.t();
Energy KT = K.t();
double tt = 1. - 2.*sqr(KplusKtildeT)/KplusKtilde2 + 2.*KT*Ktilde.t()/K2;
double tx = 2.*KplusKtildeT*KplusKtilde.x()/KplusKtilde2 - 2.*KT*Ktilde.x()/K2;
double ty = 2.*KplusKtildeT*KplusKtilde.y()/KplusKtilde2 - 2.*KT*Ktilde.y()/K2;
double tz = 2.*KplusKtildeT*KplusKtilde.z()/KplusKtilde2 - 2.*KT*Ktilde.z()/K2;
theRecoilTransformation.boost(tx/tt, ty/tt, tz/tt, tt);
// Rotate KtildeSpinCorrTrans to z-axis
Lorentz5Momentum KtildeSpinCorrTrans = theRecoilTransformation*Lorentz5Momentum(Ktilde);
Axis axis(KtildeSpinCorrTrans.vect().unit());
if( axis.perp2() > 1e-12 ) {
double sinth(sqrt(1.-sqr(axis.z())));
theRecoilTransformation.rotate(-acos(axis.z()),Axis(-axis.y()/sinth,axis.x()/sinth,0.));
}
else if( axis.z() < 0. ) {
theRecoilTransformation.rotate(Constants::pi,Axis(1.,0.,0.));
}
// Rotate from z-axis to K
Axis axis2(K.vect().unit());
if( axis2.perp2() > 1e-12 ) {
double sinth(sqrt(1.-sqr(axis2.z())));
theRecoilTransformation.rotate(acos(axis2.z()),Axis(-axis2.y()/sinth,axis2.x()/sinth,0.));
}
else if( axis2.z() < 0. ) {
theRecoilTransformation.rotate(Constants::pi,Axis(1.,0.,0.));
}
// SW 30/01/2019: Test feature only, not for release.
// Required for absorbing recoil in hard particles only
//splitRecoilMomentum(K);
// Set indicator that the transformation,
// has been calculated
theTransformationCalculated = true;
}
// If needed, insert default implementations of function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IILightKinematics::persistentOutput(PersistentOStream &) const {
//os << theTransformHardOnly;
//os << theCollinearScheme;
}
void IILightKinematics::persistentInput(PersistentIStream &, int) {
//is >> theTransformHardOnly;
//is >> theCollinearScheme;
}
ClassDescription<IILightKinematics> IILightKinematics::initIILightKinematics;
// Definition of the static class description member.
void IILightKinematics::Init() {
static ClassDocumentation<IILightKinematics> documentation
("IILightKinematics implements massless splittings "
"off an initial-initial dipole.");
/*
static Switch<IILightKinematics,bool> interfaceTransformHardOnly
("TransformHardOnly",
"[Dev only] Apply recoil transformation to colourless particles only.",
&IILightKinematics::theTransformHardOnly, false, false, false);
static SwitchOption interfaceTransformHardOnlyYes
(interfaceTransformHardOnly,
"Yes",
"Transform only colourless particles.",
true);
static SwitchOption interfaceTransformHardOnlyNo
(interfaceTransformHardOnly,
"No",
"Transform all particles.",
false);
interfaceTransformHardOnly.rank(-1);
*/
/*
static Switch<IILightKinematics,bool> interfaceCollinearScheme
("CollinearScheme",
"[experimental] Switch on or off the collinear scheme",
&IILightKinematics::theCollinearScheme, false, false, false);
static SwitchOption interfaceCollinearSchemeYes
(interfaceCollinearScheme,
"Yes",
"Switch on the collinear scheme.",
true);
static SwitchOption interfaceCollinearSchemeNo
(interfaceCollinearScheme,
"No",
"Switch off the collinear scheme",
false);
interfaceCollinearScheme.rank(-1);
*/
}
diff --git a/Shower/Dipole/Kinematics/IILightKinematics.h b/Shower/Dipole/Kinematics/IILightKinematics.h
--- a/Shower/Dipole/Kinematics/IILightKinematics.h
+++ b/Shower/Dipole/Kinematics/IILightKinematics.h
@@ -1,295 +1,287 @@
// -*- C++ -*-
//
// IILightKinematics.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IILightKinematics_H
#define HERWIG_IILightKinematics_H
//
// This is the declaration of the IILightKinematics class.
//
#include "DipoleSplittingKinematics.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IILightKinematics implements massless splittings
* off an initial-initial dipole.
*
* @see \ref IILightKinematicsInterfaces "The interfaces"
* defined for IILightKinematics.
*/
class IILightKinematics: public DipoleSplittingKinematics {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IILightKinematics();
- /**
- * The destructor.
- */
- virtual ~IILightKinematics();
- //@}
-
public:
/**
* Return the maximum pt for the given dipole scale.
*/
virtual Energy ptMax(Energy dScale,
double emX, double specX,
const DipoleIndex&,
const DipoleSplittingKernel&) const;
/**
* Return the maximum virtuality for the given dipole scale.
*/
virtual Energy QMax(Energy dScale,
double emX, double specX,
const DipoleIndex& dIndex,
const DipoleSplittingKernel&) const;
/**
* Return the pt given a virtuality.
*/
virtual Energy PtFromQ(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the virtuality given a pt.
*/
virtual Energy QFromPt(Energy scale, const DipoleSplittingInfo&) const;
/**
* Return the boundaries on the momentum fraction
*/
virtual pair<double,double> zBoundaries(Energy pt,
const DipoleSplittingInfo& dInfo,
const DipoleSplittingKernel& split) const;
/**
* Generate splitting variables given three random numbers
* and the momentum fractions of the emitter and spectator.
* Return true on success.
*/
virtual bool generateSplitting(double kappa, double xi, double phi,
DipoleSplittingInfo& dIndex,
const DipoleSplittingKernel&);
/**
* Generate the full kinematics given emitter and
* spectator momentum and a previously completeted
* DipoleSplittingInfo object.
*/
virtual void generateKinematics(const Lorentz5Momentum& pEmitter,
const Lorentz5Momentum& pSpectator,
const DipoleSplittingInfo& dInfo);
/**
* Return true, if there is a transformation which should
* be applied to all other final state particles except the ones
* involved in the splitting after having performed the splitting
*/
virtual bool doesTransform () const { return theCollinearScheme || didCollinear; }
/**
* Calculate and store a required Lorentz transformation
**/
virtual void setTransformation () ;
/*
* perform the transformation, if existing
*/
virtual void transform (PPtr& part) {
if ( !theCollinearScheme && !didCollinear ) return;
Lorentz5Momentum mom = part->momentum();
// If particle has SpinInfo check that we're
// not dealing with an intermediate spectator.
if ( part->spinInfo()
&& !(part->spinInfo()->timelike() && part->children().size() == 1 )
&& !(!part->spinInfo()->timelike() && part->parents()[0]->children().size() == 1 ) ) {
if ( !theTransformationCalculated )
setTransformation();
part->spinInfo()->transform(mom,theRecoilTransformation);
}
part->set5Momentum(mom-(2.*(KplusKtilde*mom)/KplusKtilde2)*KplusKtilde+(2.*(Ktilde*mom)/K2)*K);
}
/*
* SW 30/01/2019: Test feature only, not for release.
* Return true to only apply the transformation to non-coloured particles.
* Note this requires careful handling in DipoleEventRecord
*/
//virtual bool transformHardOnly() const { return theTransformHardOnly; }
/**
* SW 30/01/2019: Test feature only, not for release.
* Perform the recoil in the case of a decayed parton
*/
// virtual void transformHard ( PPtr& hard ) {
// if ( !theTransformationCalculated ) {
// setTransformation();
// theTransformationCalculated = true;
// }
// hard->setMomentum(splitRecoilMomentum());
// hard->rescaleMass();
// }
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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IILightKinematics> initIILightKinematics;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IILightKinematics & operator=(const IILightKinematics &) = delete;
private:
/**
* Wether or not to choose the `collinear' scheme
*/
bool theCollinearScheme;
bool didCollinear;
/**
* SW 30/01/2019: Test feature only, not for release.
* Whether to transform only hard (i.e. non-coloured) particles.
*/
//bool theTransformHardOnly;
Lorentz5Momentum K;
Energy2 K2;
Lorentz5Momentum Ktilde;
Lorentz5Momentum KplusKtilde;
Energy2 KplusKtilde2;
/**
* Store the LorentzRotation object equivalent to the
* transformation applied to the outgoing particles.
* Need this to apply to the particle SpinInfo if spin
* correlations are included.
*/
LorentzRotation theRecoilTransformation;
/**
* Bool to avoid unecessary recalculation of the
* Lorentz transformation.
*/
bool theTransformationCalculated;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IILightKinematics. */
template <>
struct BaseClassTrait<Herwig::IILightKinematics,1> {
/** Typedef of the first base class of IILightKinematics. */
typedef Herwig::DipoleSplittingKinematics NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IILightKinematics class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IILightKinematics>
: public ClassTraitsBase<Herwig::IILightKinematics> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IILightKinematics"; }
/**
* The name of a file containing the dynamic library where the class
* IILightKinematics is implemented. It may also include several, space-separated,
* libraries if the class IILightKinematics 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_IILightKinematics_H */
diff --git a/Shower/Dipole/Merging/MergingFactory.cc b/Shower/Dipole/Merging/MergingFactory.cc
--- a/Shower/Dipole/Merging/MergingFactory.cc
+++ b/Shower/Dipole/Merging/MergingFactory.cc
@@ -1,679 +1,679 @@
// -*- C++ -*-
//
// MergeboxFactory.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 MergeboxFactory class.
//
#include "MergingFactory.h"
#include "Node.h"
#include "ThePEG/Repository/Repository.h"
#include "ThePEG/Utilities/ColourOutput.h"
using namespace Herwig;
using std::ostream_iterator;
IBPtr MergingFactory::clone() const {
return new_ptr(*this);
}
IBPtr MergingFactory::fullclone() const {
return new_ptr(*this);
}
void MergingFactory::doinit(){
MatchboxFactory::doinit();
if (subProcessGroups()) {
throw InitException() << "There are no subprocess groups in merging!";
}
}
void MergingFactory::productionMode() {
if(M()<0)
for ( vector<Ptr<MatchboxAmplitude>::ptr>::iterator amp
= amplitudes().begin(); amp != amplitudes().end(); ++amp ) {
Repository::clog() << "One-loop contributions from '"
<< (**amp).name()
<< "' are not required and will be disabled.\n"
<< flush;
(**amp).disableOneLoop();
}
MatchboxFactory::productionMode();
}
void MergingFactory::fillMEsMap() {
olpProcesses().clear();
assert( getProcesses().size() == 1 );
processMap[0] = getProcesses()[0];
if ( MH()->M() >= 0 )
setHighestVirt(processMap[0].size()+MH()->M());
MH()->N0(processMap[0].size());
for ( int i = 1 ; i <= MH()->N() ; ++i ) {
processMap[i] = processMap[i - 1];
processMap[i].push_back("j");
}
for ( int i = 0 ; i <= MH()->N() ; ++i ) {
const bool below_maxNLO = i < MH()->M() + 1;
vector<MatchboxMEBasePtr> ames
= makeMEs(processMap[i], orderInAlphaS() + i, below_maxNLO );
copy(ames.begin(), ames.end(), back_inserter(pureMEsMap()[i]));
}
}
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
void MergingFactory::prepare_BV(int i) {
// check if we have virtual contributions
bool haveVirtuals = true;
for ( auto born : pureMEsMap()[i]) {
prepareME(born);
if ( born->isOLPTree() ) {
int id = orderOLPProcess(born->subProcess(),
born->matchboxAmplitude(),
ProcessType::treeME2);
born->olpProcess(ProcessType::treeME2,id);
id = orderOLPProcess(born->subProcess(),
born->matchboxAmplitude(),
ProcessType::colourCorrelatedME2);
born->olpProcess(ProcessType::colourCorrelatedME2,id);
bool haveGluon = false;
for ( const auto & p : born->subProcess().legs )
if ( p->id() == 21 ) {
haveGluon = true;
break;
}
if ( haveGluon ) {
id = orderOLPProcess(born->subProcess(),
born->matchboxAmplitude(),
ProcessType::spinColourCorrelatedME2);
born->olpProcess(ProcessType::spinColourCorrelatedME2,id);
}
}
if ( born->isOLPLoop() && i <= MH()->M() ) {
int id = orderOLPProcess(born->subProcess(),
born->matchboxAmplitude(),
ProcessType::oneLoopInterference);
born->olpProcess(ProcessType::oneLoopInterference,id);
if ( !born->onlyOneLoop() && born->needsOLPCorrelators() ) {
id = orderOLPProcess(born->subProcess(),
born->matchboxAmplitude(),
ProcessType::colourCorrelatedME2);
born->olpProcess(ProcessType::colourCorrelatedME2,id);
}
}
haveVirtuals &= born->haveOneLoop();
}
// check for consistent conventions on virtuals, if we are to include MH()->M()
if (!(i > MH()->M()||haveVirtuals))
throw InitException()
<< MH()->M()
<< " NLO corrections requested,\n"
<< "but no virtual contributions are found.";
}
void MergingFactory::prepare_R(int i) {
for ( auto real : pureMEsMap()[i])
prepareME(real);
}
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
void MergingFactory::getVirtuals(MatchboxMEBasePtr nlo, bool clone){
const auto & partons = nlo->diagrams().front()->partons();
for ( auto I : DipoleRepository::insertionIOperators(dipoleSet()) )
if ( I->apply(partons) ){
auto myI = I;
if ( clone ) myI = I->cloneMe();
nlo->virtuals().push_back(myI);
}
for ( auto PK : DipoleRepository::insertionPKOperators(dipoleSet()) )
if ( PK->apply(partons) ){
auto myPK = PK;
if ( clone ) myPK = PK->cloneMe();
nlo->virtuals().push_back(myPK);
}
}
void MergingFactory::pushB(MatchboxMEBasePtr born, int i) {
MatchboxMEBasePtr bornme = born->cloneMe();
bornme->maxMultCKKW(1);
bornme->minMultCKKW(0);
string pname = fullName() + "/" + bornme->name() + ".Born";
if ( !(generator()->preinitRegister(bornme, pname)) )
throw InitException()
<< "Born ME "<< pname << " already existing.";
NodePtr clusternode = new_ptr(Node(bornme, 0, MH()));
clusternode->deepHead(clusternode);
MH()->firstNodeMap(bornme,clusternode);
bornme->merger(MH());
vector<NodePtr> current = {{clusternode}};
vector<NodePtr> children;
unsigned int k = 1;
while ( ! thePureMEsMap[i - k].empty() ) {
for ( auto tmp : current ){//j
tmp->birth(thePureMEsMap[i - k]);
for ( auto tmpchild : tmp->children() ) {//m
children.push_back(tmpchild);
}
}
current = children;
children.clear();
++k;
}
if ( MH()->N() > i )
bornme->needsCorrelations();
else
bornme->needsNoCorrelations();
bornme->cloneDependencies();
MEs().push_back(bornme);
}
void MergingFactory::pushV(MatchboxMEBasePtr born, int i) {
MatchboxMEBasePtr nlo = born->cloneMe();
string pname = fullName() + "/" + nlo->name() + ".Virtual";
if ( !(generator()->preinitRegister(nlo, pname)) )
throw InitException()
<< "Virtual ME "<< pname << " already existing.";
////////////////////////////////////NLO///////////////////////////
nlo->virtuals().clear();
getVirtuals(nlo , false);
if ( nlo->virtuals().empty() )
throw InitException()
<< "No insertion operators have been found for "
<< born->name() << ".\n";
nlo->doOneLoopNoBorn();
////////////////////////////////////NLO///////////////////////////
NodePtr clusternode = new_ptr(Node(nlo, 0,MH()));
clusternode->deepHead(clusternode);
clusternode->virtualContribution(true);
MH()->firstNodeMap(nlo,clusternode);
nlo->merger(MH());
vector<NodePtr> current = {{clusternode}};
vector<NodePtr> children;
unsigned int k = 1;
while ( ! thePureMEsMap[i - k].empty() ) {
for ( auto tmp : current ){
tmp->birth(thePureMEsMap[i - k]);
for ( auto tmpchild : tmp->children())
children.push_back(tmpchild);
}
current = children;
children.clear();
++k;
}
if ( nlo->isOLPLoop() ) {
int id = orderOLPProcess(nlo->subProcess(),
born->matchboxAmplitude(),
ProcessType::oneLoopInterference);
nlo->olpProcess(ProcessType::oneLoopInterference,id);
if ( !nlo->onlyOneLoop() && nlo->needsOLPCorrelators() ) {
id = orderOLPProcess(nlo->subProcess(),
born->matchboxAmplitude(),
ProcessType::colourCorrelatedME2);
nlo->olpProcess(ProcessType::colourCorrelatedME2,id);
}
}
nlo->needsCorrelations();
nlo->cloneDependencies();
MEs().push_back(nlo);
}
void MergingFactory::pushR(MatchboxMEBasePtr born, int i) {
MatchboxMEBasePtr bornme = born->cloneMe();
string pname = fullName() + "/" + bornme->name() + ".Real";
if ( !(generator()->preinitRegister(bornme, pname)) )
throw InitException()
<< "Subtracted ME " << pname << " already existing.";
NodePtr clusternode = new_ptr(Node(bornme, 1, MH()));
clusternode->deepHead(clusternode);
clusternode->subtractedReal(true);
MH()->firstNodeMap(bornme,clusternode);
bornme->merger(MH());
vector<NodePtr> current = {{clusternode}};
vector<NodePtr> children;
unsigned int k = 1;
while ( ! thePureMEsMap[i - k].empty() ) {
for ( auto tmp : current ){
tmp->birth(thePureMEsMap[i - k]);
for ( auto tmpchild : tmp->children())
children.push_back(tmpchild);
}
current = children;
children.clear();
++k;
}
if(clusternode->children().empty()){
// This is a finite real contribution.
// This process is included in the LO merging.
return;
}
if ( MH()->N() > i ) bornme->needsCorrelations();
else bornme->needsNoCorrelations();
bornme->cloneDependencies(pname);
MEs().push_back(bornme);
}
// MergingFactory should never order OLPs here,
// they're done elsewhere.
void MergingFactory::orderOLPs() {}
#include "ThePEG/Utilities/StringUtils.h"
vector<string> MergingFactory::parseProcess(string in) {
vector<string> process = StringUtils::split(in);
if ( process.size() < 3 )
throw Exception()
<< "MatchboxFactory: Invalid process."<< Exception::runerror;
for ( string & p : process) {
p = StringUtils::stripws(p);
}
theN = 0;
bool prodprocess = true;
vector<string> result;
for ( const string & p : process ) {
if ( p == "->" )
continue;
if (p=="[") {
prodprocess = false;
} else if (p=="]") {
prodprocess = false;
// TODO what if there's stuff after the bracket?
assert( p == process.back() );
break;
} else if (p=="[j") {
prodprocess = false;
++theN;
} else if (p=="j" && !prodprocess) {
++theN;
prodprocess = false;
} else if (p=="j]") {
++theN;
prodprocess = false;
// TODO what if there's stuff after the bracket?
assert( p == process.back() );
break;
} else if ( prodprocess ) {
result.push_back(p);
} else {
throw InitException()
<< "Unknown particle class \"" << p << '"'
<< " in the process definition merging bracket.\n"
<< "Only jets (\"j\") are supported at the moment.";
}
}
return result;
}
#include "Herwig/Utilities/Progress.h"
void MergingFactory::setup() {
useMe();
DipoleShowerHandlerPtr dsh=dynamic_ptr_cast<DipoleShowerHandlerPtr>(this->CKKWHandler());
if(! dsh )throw InitException() << "The showerhandler for the MergingFactory must be the DipoleShower. ";
dsh->setMerger(MH());
MH()->setFactory(this);
MH()->setDipoleShower(dsh);
if(!ransetup){
generator()->log() <<"\nStarting merging setup.\n\n";
olpProcesses().clear();
externalAmplitudes().clear();
// We set the couplings in the ME to be fixed
// and reweight in the history weight for this.
setFixedCouplings(true);
setFixedQEDCouplings(true);
// rebind the particle data objects, can't use rebind() function
for ( auto & g : particleGroups()) {
for ( auto & p : g.second) {
p = getParticleData(p->id());
}
}
const PDVector& partons = particleGroups()["j"];
unsigned int nl = 0;
- for ( const auto p : partons ) {
+ for ( const auto & p : partons ) {
const Energy mass = p->hardProcessMass();
const long pid = p->id();
if ( abs(pid) < 7 && mass == ZERO )
++nl;
if ( pid > 0 && pid < 7 && mass == ZERO )
nLightJetVec( pid );
if ( pid > 0 && pid < 7 && mass != ZERO )
nHeavyJetVec( pid );
}
nLight(nl/2);
const PDVector& partonsInP = particleGroups()["p"];
- for ( const auto pip : partonsInP )
+ for ( const auto & pip : partonsInP )
if ( pip->id() > 0 && pip->id() < 7 && pip->hardProcessMass() == ZERO )
nLightProtonVec( pip->id() );
// fill the amplitudes
if ( !amplitudes().empty() ) fillMEsMap();
// Use the colour basis of the first element of amplitudes
// to set the large N colour basis for the MergingHelper
assert(!amplitudes().empty() );
if ( amplitudes()[0]->colourBasis() ) {
auto largeNBasis =
amplitudes()[0]->colourBasis()->cloneMe();
largeNBasis->clear();
largeNBasis->doLargeN();
MH()->largeNBasis(largeNBasis);
}
// prepare the Born and virtual matrix elements
for ( int i = 0 ; i <= max(0, MH()->N()) ; ++i ) prepare_BV(i);
// prepare the real emission matrix elements
for ( int i = 0 ; i <= MH()->N() ; ++i ) prepare_R(i);
if (MH()->N()<=MH()->M()) {
throw InitException() << "Merging: The number of NLOs need to be"
<< "\nsmaller than the number of LO processes.\n";
}
// Order the external Amplitudes.
orderOLPs();
// start creating matrix elements
MEs().clear();
// count the subprocesses
size_t numb = 0;
size_t numv = 0;
size_t numr = 0;
for (int i = 0; i <= max(0, MH()->N()) ; ++i ) {
for ( auto born : thePureMEsMap[i] ) {
if (bornContributions()
) {
numb++;
}
}
}
for (int i = 0 ; i <=max(0, MH()->N()); ++i )
for ( auto virt : thePureMEsMap[i] )
if ( virtualContributions() && i <= MH()->M()) {
numv++;
}
for (int i = 1; i <= max(0, MH()->N()) ; ++i )
for ( auto real : thePureMEsMap[i] )
if (realContributions() && i <= MH()->M() + 1 ){
numr++;
}
if(int(numb+numv+numr) < theChunk){
throw InitException() << "You try to chunk (Chunk="<<theChunk<<") the number of "<<
"subprocesses ("<<int(numb+numv+numr)<<") into more parts than there are subprocesses.";
}
if(theChunk<theChunkPart)
throw InitException() <<" The ChunkPart is larger than the Chunk.";
if(theChunk > 0 && theChunkPart == 0 )
throw InitException() <<" Set the ChunkPart ( = "<<theChunkPart<<" ) to i in [1,..,N] with N=Chunk.";
if ( theChunkPart != 0 )
generator()->log() << ANSI::yellow
<< "\n\nWarning: \nYou split up the runs into theChunks. This is no standard feature."
<< "\nYou are now responsible to make sure to run all theChunk parts."
<< "\nThis setup run is for: " << theChunkPart << "/" << theChunk<<"\n\n ";
generator()->log() << ANSI::red << "Preparing Merging: ";
generator()->log() << ANSI::green << numb << " x Born " << ANSI::red;
if (MH()->M()>-1) {
generator()->log() << ANSI::yellow << numv << " x Virtual ";
generator()->log() << ANSI::blue << numr << " x Real " << ANSI::red << flush;
}
int countchunk=0;
progress_display progressBar{ numb+numv+numr, generator()->log() };
// insert the born contributions to ME vector
for (int i = 0; i <= max(0, MH()->N()) ; ++i )
for ( auto born : thePureMEsMap[i])
if (bornContributions() ){
countchunk++; // theChunkPart is in [1,...,theChunk]
if ( theChunk == 0 || theChunkPart == countchunk ) pushB( born , i );
if ( countchunk == theChunk ) countchunk=0;
generator()->log() << ANSI::green;
++progressBar;
generator()->log() << ANSI::reset;
}
// insert the virtual contributions to ME vector
for (int i = 0 ; i <=max(0, MH()->N()); ++i )
for ( auto virt : thePureMEsMap[i])
if ( virtualContributions() && i <= MH()->M()){
countchunk++;// theChunkPart is in [1,...,theChunk]
if ( theChunk == 0 || theChunkPart == countchunk ) pushV(virt, i);
if ( countchunk == theChunk ) countchunk=0;
generator()->log() << ANSI::yellow;
++progressBar;
}
// insert the real contributions to ME vector
for (int i = 1; i <= max(0, MH()->N()) ; ++i )
for ( auto real : thePureMEsMap[i] )
if (realContributions()&& i <= MH()->M() + 1 ){
countchunk++;// theChunkPart is in [1,...,theChunk]
if ( theChunk == 0 || theChunkPart == countchunk ) pushR(real, i);
if ( countchunk == theChunk ) countchunk=0;
generator()->log() << ANSI::blue;
++progressBar;
}
generator()->log() << ANSI::reset;
if ( !externalAmplitudes().empty() ) {
generator()->log() << "Initializing external amplitudes." << endl;
progress_display progressBar{ externalAmplitudes().size(), generator()->log() };
- for ( const auto ext : externalAmplitudes() ) {
+ for ( const auto & ext : externalAmplitudes() ) {
if ( ! ext->initializeExternal() ) {
throw InitException()
<< "error: failed to initialize amplitude '" << ext->name() << "'\n";
}
++progressBar;
}
generator()->log()
<< "---------------------------------------------------" << endl;
}
if ( !olpProcesses().empty() ) {
generator()->log() << "Initializing one-loop provider(s)." << endl;
map<Ptr<MatchboxAmplitude>::tptr, map<pair<Process, int>, int> > olps;
- for (const auto oit : olpProcesses()) {
+ for (const auto & oit : olpProcesses()) {
olps[oit.first] = oit.second;
}
progress_display progressBar{ olps.size(), generator()->log() };
- for ( const auto olpit : olps ) {
+ for ( const auto & olpit : olps ) {
if ( !olpit.first->startOLP(olpit.second) ) {
throw InitException() << "error: failed to start OLP for amplitude '" << olpit.first->name() << "'\n";
}
++progressBar;
}
generator()->log()
<< "---------------------------------------------------\n" << flush;
}
generator()->log() <<"\nGenerated "<<MEs().size()<<" Subprocesses.\n"<<flush;
generator()->log()
<< "---------------------------------------------------\n" << flush;
generator()->log() <<"\n\n" << ANSI::red
<<"Note: Due to the unitarization of the higher "
<<"\nmultiplicities, the individual cross sections "
<<"\ngiven in the integration and run step are not"
<<"\nmeaningful without merging." << ANSI::reset << endl;
ransetup=true;
}
}
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
void MergingFactory::persistentOutput(PersistentOStream & os) const {
os
<< theonlymulti
<< ransetup
<< processMap << theMergingHelper <<theM<<theN<<theNonQCDCuts<<theChunk<<theChunkPart;
}
void MergingFactory::persistentInput(PersistentIStream & is, int) {
is
>> theonlymulti
>> ransetup
>> processMap >> theMergingHelper >>theM>>theN>>theNonQCDCuts>>theChunk>>theChunkPart;
}
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Command.h"
void MergingFactory::Init() {
static Parameter<MergingFactory, int> interfaceonlymulti("onlymulti",
"Calculate only the ME with k additional partons.",
&MergingFactory::theonlymulti, -1, -1, 0,
false, false, Interface::lowerlim);
static Switch<MergingFactory, bool> interface_Unitarized("Unitarized",
"Unitarize the cross section (default is unitarised. NLO merging must be unitarised).",
&MergingFactory::unitarized, true, false, false);
static SwitchOption interface_UnitarizedYes(interface_Unitarized, "Yes",
"Switch on the unitarized cross section.", true);
static SwitchOption interface_UnitarizedNo(interface_Unitarized, "No",
"Switch off the unitarized cross section.", false);
static Reference<MergingFactory,Merger> interfaceMergingHelper("MergingHelper",
"Pointer to the Merging Helper.",
&MergingFactory::theMergingHelper, false, false, true, true, false);
static Parameter<MergingFactory, int> interfaceaddNLOLegs("NLOProcesses",
"Set the number of virtual corrections to consider. 0 is default for no virtual correction.",
&MergingFactory::theM, 0, 0, 0, false, false, Interface::lowerlim);
static Reference<MergingFactory, Cuts > interfaceNonQcdCuts("NonQCDCuts",
"Cut on non-QCD modified observables. Be carefull!",
&MergingFactory::theNonQCDCuts, false, false, true, true, false);
static Parameter<MergingFactory, int> interfacetheChunk("Chunk",
"Cut the number of subprocesses into n theChunks.",
&MergingFactory::theChunk, -1, -1, 0,
false, false, Interface::lowerlim);
static Parameter<MergingFactory, int> interfacetheChunkPart("ChunkPart",
"If theChunk is larger then 0, set this parameter to the n'th part. Make sure to add the ChunksParts afterwards.",
&MergingFactory::theChunkPart, -1, -1, 0,
false, false, Interface::lowerlim);
}
// *** Attention *** The following static variable is needed for the type
// description system in ThePEG. Please check that the template arguments
// are correct (the class and its base class), and that the constructor
// arguments are correct (the class name and the name of the dynamically
// loadable library where the class implementation can be found).
DescribeClass<MergingFactory, Herwig::MatchboxFactory>
describeHerwigMergingFactory("Herwig::MergingFactory", "HwDipoleShower.so");
diff --git a/Shower/Dipole/Merging/Node.cc b/Shower/Dipole/Merging/Node.cc
--- a/Shower/Dipole/Merging/Node.cc
+++ b/Shower/Dipole/Merging/Node.cc
@@ -1,458 +1,456 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the Node class.
//
#include "Node.h"
#include "MergingFactory.h"
#include "Merger.h"
using namespace Herwig;
Node::Node(MatchboxMEBasePtr nodeME, int cutstage, MergerPtr mh)
:Interfaced(),
thenodeMEPtr(nodeME),
thedipol(),
theparent(),
theCutStage(cutstage),
theSubtractedReal(false),
theVirtualContribution(false),
theMergingHelper(mh)
{
nodeME->maxMultCKKW(1);
nodeME->minMultCKKW(0);
}
Node::Node(NodePtr deephead,
NodePtr head,
SubtractionDipolePtr dipol,
MatchboxMEBasePtr nodeME,
int cutstage)
:Interfaced(), thenodeMEPtr(nodeME),
thedipol(dipol),
theparent(head),
theDeepHead(deephead),
theCutStage(cutstage),
theSubtractedReal(false),
theVirtualContribution(false),
theMergingHelper() //The subnodes have no merging helper
{
}
-Node::~Node() { }
-
SubtractionDipolePtr Node::dipole() const {
return thedipol;
}
/** returns the matrix element pointer */
const MatchboxMEBasePtr Node::nodeME() const {
return thenodeMEPtr;
}
/** access the matrix element pointer */
MatchboxMEBasePtr Node::nodeME() {
return thenodeMEPtr;
}
pair<PVector , PVector> Node::getInOut( ){
PVector in;
const auto me= nodeME();
const auto pd=me->mePartonData();
for( auto i : {0 , 1} )
in.push_back(pd[i]->produceParticle( me->lastMEMomenta()[i] ) );
PVector out;
for ( size_t i = 2;i< pd.size();i++ ){
PPtr p = pd[i]->produceParticle( me->lastMEMomenta()[i] );
out.push_back( p );
}
return { in , out };
}
int Node::legsize() const {return nodeME()->legsize();}
NodePtr Node::randomChild() {
return thechildren[UseRandom::irnd(thechildren.size())];
}
bool Node::allAbove(Energy pt) {
for (NodePtr child : thechildren)
if ( child->pT() < pt )
return false;
return true;
}
Energy Node::maxChildPt(){
Energy maxi=-1*GeV;
for (NodePtr child : thechildren)maxi=max(child->pT(),maxi);
return maxi;
}
bool Node::isInHistoryOf(NodePtr other) {
while (other->parent()) {
if (other == this)
return true;
other = other->parent();
}
return false;
}
void Node::flushCaches() {
if (didflush) return;
didflush=true;
for ( auto const & ch: thechildren) {
ch->xcomb()->clean();
ch->nodeME()->flushCaches();
ch->flushCaches();
}
}
void Node::setKinematics() {
for (auto const & ch: thechildren) {
ch->dipole()->setXComb(ch->xcomb());
ch->dipole()->setKinematics();
ch->nodeME()->setKinematics();
ch->setKinematics();
}
}
void Node::clearKinematics() {
for (auto const & ch: thechildren) {
ch->dipole()->setXComb(ch->xcomb());
ch->nodeME()->clearKinematics();
ch->dipole()->clearKinematics();
ch->clearKinematics();
}
}
bool Node::generateKinematics(const double *r, bool directCut) {
didflush=false;
// If there are no children to the child process we are done.
if(children().empty()) return true;
assert(parent());
if ( ! directCut && pT() < deepHead()->MH()->mergePt()) {
// Real emission:
// If there are children to the child process,
// we now require that all subsequent children
// with pt < merging scale are in their ME region.
// Since the possible children of the real emission
// contribution are now in their ME region,
// it is clear that a second clustering is possible
// -- modulo phase space restrictions.
// Therefore the real emission contribution
// are unitarised and the cross section is
// hardly modified.
auto inOutPair = getInOut();
NodePtr rc = randomChild();
rc->dipole()->setXComb(rc->xcomb());
if(!rc->dipole()->generateKinematics(r))assert(false);
// If not in ME -> return false
if(!deepHead()->MH()->matrixElementRegion( inOutPair.first ,
inOutPair.second ,
rc->pT() ,
deepHead()->MH()->mergePt() ) )return false;
}
for (auto & ch : children() ) {
ch->dipole()->setXComb(ch->xcomb());
if ( !ch->dipole()->generateKinematics(r) ) { assert(false); }
ch->generateKinematics( r, true);
}
return true;
}
bool Node::firstgenerateKinematics(const double *r, bool directCut) {
didflush=false;
// This is called form the merging helper for the first node. So:
assert(!parent());
assert(xcomb());
if(MH()->treefactory()->nonQCDCuts()){
tcPDVector outdata(xcomb()->mePartonData().begin()+2,
xcomb()->mePartonData().end());
vector<LorentzMomentum> outmomenta(xcomb()->meMomenta().begin()+2,
xcomb()->meMomenta().end());
if ( !MH()->treefactory()->nonQCDCuts()->passCuts(outdata,outmomenta,
xcomb()->mePartonData()[0],
xcomb()->mePartonData()[1]) )
return false;
}
///// This should not be needed!!!
///// ( Warning inMerger::matrixElementRegion gets triggered.)
flushCaches();
//Set here the new merge Pt for the next phase space point.( Smearing!!!)
MH()->smearMergePt();
// If there are no children to this node, we are done here:
if (children().empty())
return true;
// directCut is for born and for virtual contributions.
// if directCut is true, then cut on the first ME region.
// call recursiv generate kinematics for subsequent nodes.
if ( directCut ){
auto inOutPair = getInOut();
NodePtr rc = randomChild();
rc->dipole()->setXComb(rc->xcomb());
if ( !rc->dipole()->generateKinematics(r) ) { return false; }
rc->nodeME()->setXComb(rc->xcomb());
if(!MH()->matrixElementRegion( inOutPair.first ,
inOutPair.second ,
rc->pT() ,
MH()->mergePt() ) ){
return false;
}
}
for (auto const & ch: thechildren) {
ch->dipole()->setXComb(ch->xcomb());
if ( !ch->dipole()->generateKinematics(r) ) { cout<<"\nCould not generate dipole kinematics";;return false; }
if( ! ch->generateKinematics(r,directCut) )return false;
}
return true;
}
StdXCombPtr Node::xcomb() const {
assert(thexcomb);
return thexcomb;
}
StdXCombPtr Node::xcomb(){
if(thexcomb)return thexcomb;
assert(parent());
thexcomb=dipole()->makeBornXComb(parent()->xcomb());
xcomb()->head(parent()->xcomb());
dipole()->setXComb(thexcomb);
return thexcomb;
}
void Node::setXComb(tStdXCombPtr xc) {
assert ( !parent() );
thexcomb=xc;
assert(thexcomb->lastParticles().first);
}
#include "Herwig/MatrixElement/Matchbox/Base/DipoleRepository.h"
void Node::birth(const vector<MatchboxMEBasePtr> & vec) {
// produce the children
vector<SubtractionDipolePtr> dipoles =
nodeME()->getDipoles(DipoleRepository::dipoles(
nodeME()->factory()->dipoleSet()), vec, true);
for ( auto const & dip : dipoles ) {
dip->doSubtraction();
NodePtr node = new_ptr(Node(theDeepHead,
this,
dip,
dip->underlyingBornME(),
theDeepHead->cutStage()));
thechildren.push_back(node);
}
}
vector<NodePtr> Node::getNextOrderedNodes(bool normal, double hardScaleFactor) const {
vector<NodePtr> temp = children();
vector<NodePtr> res;
for (NodePtr const & child : children()) {
if(deepHead()->MH()->mergePt()>child->pT()) {
res.clear();
return res;
}
}
for (NodePtr const & child: children()) {
if (parent()&& normal) {
if ( child->pT() < pT() ) {
continue;
}
}
if ( child->children().size() != 0 ) {
for (NodePtr itChild: child->children()) {
if( itChild->pT() > child->pT()&&child->inShowerPS(itChild->pT()) ) {
res.push_back(child);
break;
}
}
}
else {
const auto sc=child->nodeME()->factory()->scaleChoice();
sc->setXComb(child->xcomb());
if ( sqr(hardScaleFactor)*
sc->renormalizationScale() >= sqr(child->pT()) &&
child->inShowerPS(hardScaleFactor*sqrt(sc->renormalizationScale()))) {
res.push_back(child);
}
}
}
return res;
}
bool Node::inShowerPS(Energy hardpT)const {
// Here we decide if the current phase space
// point can be reached from the underlying Node.
// Full phase space available -> Tilde Kinematic is always fine.
if(deepHead()->MH()->openZBoundaries()==1)
return true;
double z_ = dipole()->lastZ();
// restrict according to hard scale
if(deepHead()->MH()->openZBoundaries()==0){
pair<double, double> zbounds =
dipole()->tildeKinematics()->zBounds(pT(), hardpT);
return (zbounds.first<z_&&z_<zbounds.second);
}
assert(false);
return false;
}
NodePtr Node::getHistory(bool normal, double hardScaleFactor) {
NodePtr res = this;
vector<NodePtr> temp = getNextOrderedNodes(normal, hardScaleFactor);
Energy minpt = Constants::MaxEnergy;
Selector<NodePtr> subprosel;
while (temp.size() != 0) {
minpt = Constants::MaxEnergy;
subprosel.clear();
for (NodePtr const & child : temp) {
// colour basis is not strictly needed for evaluating the colour correlator
//assert(deepHead()->MH()->largeNBasis());
if( child->dipole()->underlyingBornME()->largeNColourCorrelatedME2(
{child->dipole()->bornEmitter(),
child->dipole()->bornSpectator()},
deepHead()->MH()->largeNBasis()) != 0.
) {
double weight = 1.;
if ( deepHead()->MH()->chooseHistory() == 0 )
weight = abs(child->dipole()->dSigHatDR()/nanobarn);
else if ( deepHead()->MH()->chooseHistory() == 1 )
weight = abs(child->dipole()->dSigHatDR()/child->nodeME()->dSigHatDRB());
else if ( deepHead()->MH()->chooseHistory() == 2 )
weight = 1.;
else if ( deepHead()->MH()->chooseHistory() == 3 )
weight = 1_GeV/child->pT();
else
assert(false);
if(weight != 0.) {
subprosel.insert(weight , child);
minpt = min(minpt, child->pT());
}
}
}
if (subprosel.empty())
return res;
res = subprosel.select(UseRandom::rnd());
temp = res->getNextOrderedNodes(true, hardScaleFactor);
}
return res;
}
pair<CrossSection, CrossSection> Node::calcDipandPS(Energy scale)const {
return dipole()->dipandPs(sqr(scale), deepHead()->MH()->largeNBasis());
}
CrossSection Node::calcPs(Energy scale)const {
return dipole()->ps(sqr(scale), deepHead()->MH()->largeNBasis());
}
CrossSection Node::calcDip(Energy scale)const {
return dipole()->dip(sqr(scale));
}
IBPtr Node::clone() const {
return new_ptr(*this);
}
IBPtr Node::fullclone() const {
return new_ptr(*this);
}
#include "ThePEG/Persistency/PersistentOStream.h"
void Node::persistentOutput(PersistentOStream & os) const {
os <<
thexcomb<<
thenodeMEPtr<<
thedipol<<
thechildren<<
theparent<<
theProjector<<
theDeepHead<<
theCutStage<<
ounit(theRunningPt, GeV)<<
theSubtractedReal<<
theVirtualContribution<<
theMergingHelper;
}
#include "ThePEG/Persistency/PersistentIStream.h"
void Node::persistentInput(PersistentIStream & is, int) {
is >>
thexcomb>>
thenodeMEPtr>>
thedipol>>
thechildren>>
theparent>>
theProjector>>
theDeepHead>>
theCutStage>>
iunit(theRunningPt, GeV)>>
theSubtractedReal>>
theVirtualContribution>>
theMergingHelper;
}
// *** 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).
#include "ThePEG/Utilities/DescribeClass.h"
DescribeClass<Node, Interfaced>
describeHerwigNode("Herwig::Node", "HwDipoleShower.so");
void Node::Init() {
static ClassDocumentation<Node>
documentation("There is no documentation for the Node class");
}
diff --git a/Shower/Dipole/Merging/Node.h b/Shower/Dipole/Merging/Node.h
--- a/Shower/Dipole/Merging/Node.h
+++ b/Shower/Dipole/Merging/Node.h
@@ -1,242 +1,240 @@
// -*- C++ -*-
#ifndef Herwig_Node_H
#define Herwig_Node_H
//
// This is the declaration of the Node class.
//
#include "Node.fh"
#include "MergingFactory.fh"
#include "Merger.h"
#include "ThePEG/Config/ThePEG.h"
#include "ThePEG/Config/std.h"
#include "ThePEG/Interface/Interfaced.h"
#include "Herwig/MatrixElement/Matchbox/Base/MatchboxMEBase.fh"
#include "Herwig/MatrixElement/Matchbox/Dipoles/SubtractionDipole.fh"
#include "Herwig/Shower/Dipole/Base/DipoleEventRecord.h"
#include "ThePEG/MatrixElement/MEBase.h"
#include <vector>
namespace Herwig {
using namespace ThePEG;
/**
* The Node class represents a part of the shower history
* in the merging procedure.
* Each node can search for its "childen" in the "birth" step.
* The children processes that can be created by clustering two legs
* with a given spectator -- just like in the shower.
* To perform the "birth" a vector of processes is given to the node
* and the possible dipoles are given by the factory object.
*
*
* @see \ref NodeInterfaces "The interfaces"
* defined for Node.
*/
class Node : public Interfaced {
public:
/** @name Standard constructors and destructors. */
//@{
Node (){};
// constructor for first nodes
Node(MatchboxMEBasePtr nodeME , int cutstage , MergerPtr mh );
// another constructor for underlying nodes
Node(NodePtr deephead,
NodePtr head,
SubtractionDipolePtr dipol,
MatchboxMEBasePtr nodeME,
int cutstage);
- /// The destructor.
- virtual ~Node();
//@}
public:
// get children from vector<MatchboxMEBasePtr>
void birth(const vector<MatchboxMEBasePtr> & vec);
/// recursive setXComb. proStage is the number of clusterings
/// before the projectors get filled.
void setXComb(tStdXCombPtr xc);
/// calculate the dipole and ps approximation
pair<CrossSection, CrossSection> calcDipandPS(Energy scale)const;
/// calculate the ps approximation
CrossSection calcPs(Energy scale)const;
/// calculate the dipole
CrossSection calcDip(Energy scale)const;
/// recursive flush caches and clean up XCombs.
void flushCaches();
/// recursive clearKinematics
void clearKinematics();
/// recursive setKinematics
void setKinematics();
/// recursive generateKinematics using tilde kinematics of the dipoles
bool generateKinematics(const double *r, bool directCut);
/// generate the kinamatics of the first node
bool firstgenerateKinematics(const double *r, bool directCut);
//return the ME
const MatchboxMEBasePtr nodeME() const;
//return the node ME
MatchboxMEBasePtr nodeME();
//return the parent Node
NodePtr parent() const {return theparent;}
/// vector of children nodes created in birth
vector< NodePtr > children() const {return thechildren;}
//pick a random child (flat)
NodePtr randomChild();
/// true if all children show scales above pt
bool allAbove(Energy pt);
/// return maximum of all child pts.
Energy maxChildPt();
/// true if the node is in the history of other.
bool isInHistoryOf(NodePtr other);
/// legsize of the node ME
int legsize() const;
/// set the first node (first men). only use in factory
void deepHead(NodePtr deephead) {theDeepHead = deephead;}
/// return the first node
NodePtr deepHead() const {return theDeepHead;}
/// returns the dipol of the node.
SubtractionDipolePtr dipole() const;
/// return the xcomb
StdXCombPtr xcomb() const;
/// return the xcomb (if not created, create one from head)
StdXCombPtr xcomb() ;
/// return the current running pt
Energy runningPt() const { return theRunningPt; }
/// set the current running pt
void runningPt(Energy x) { theRunningPt=x; }
/// return the cut stage to cut on merging pt in generate kinematics
int cutStage() const { return theCutStage; }
/// get a vector of the next nodes, ordered in pt (and in parton shower phace space)
vector<NodePtr> getNextOrderedNodes(bool normal=true, double hardscalefactor=1.) const;
//true if the node is in shower history for a given pt
bool inShowerPS(Energy hardpt)const;
//get the history
NodePtr getHistory(bool normal=true, double hardscalefactor=1.);
//true if node correspond to a subtracted real.
bool subtractedReal() const {return theSubtractedReal;}
/// set if node correspont to a subtracted real.
void subtractedReal(bool x) { theSubtractedReal = x;}
//true if node correspond to a virtual contribution.
bool virtualContribution() const { return theVirtualContribution ;}
/// set if node correspont to a virtual contribution.
void virtualContribution(bool x) {theVirtualContribution = x;}
//pointer to the merging helper
MergerPtr MH()const{return theMergingHelper;}
/// set the merging helper
void MH(MergerPtr a){theMergingHelper=a;}
/// pT of the dipole
Energy pT()const{return dipole()->lastPt();}
/// get incoming and outgoing particles (TODO: expensive)
pair<PVector , PVector> getInOut();
private:
/// the Matrixelement representing this node.
MatchboxMEBasePtr thenodeMEPtr;
/// the dipol used to substract
/// and generate kinematics using tilde kinematics
SubtractionDipolePtr thedipol;
/// the parent node
NodePtr theparent;
/// The godfather node of whole tree.(Firstnode)
NodePtr theDeepHead;
/**
* The CutStage is number of clusterings which are possible without
* introducing a merging scale to cut away singularities.
* -> subtracted MEs have the CutStage 1.
* -> virtual and normal tree level ME get 0.
*/
int theCutStage;
/// flag to tell if node is subtracted real
bool theSubtractedReal;
/// flag to tell if node is virtual contribution
bool theVirtualContribution;
/// the merging helper (should be static)
MergerPtr theMergingHelper;
//the xcomb of the node
StdXCombPtr thexcomb;
/// vector of the children node
vector< NodePtr > thechildren;
/// the current running pt
Energy theRunningPt;
/// The nodes of the projection stage.
NodePtr theProjector;
/// flag not to enter infinite loop. (There should be a better solution...)
bool didflush=false;
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.
*/
Node & operator=(const Node &) = delete;
};
}
#endif /* Herwig_Node_H */
diff --git a/Shower/Dipole/Utility/ConstituentReshuffler.cc b/Shower/Dipole/Utility/ConstituentReshuffler.cc
--- a/Shower/Dipole/Utility/ConstituentReshuffler.cc
+++ b/Shower/Dipole/Utility/ConstituentReshuffler.cc
@@ -1,622 +1,617 @@
// -*- C++ -*-
//
// ConstituentReshuffler.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 ConstituentReshuffler class.
//
#include <config.h>
#include "ConstituentReshuffler.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include <limits>
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "DipolePartonSplitter.h"
#include "Herwig/Utilities/GSLBisection.h"
#include "Herwig/Shower/Dipole/DipoleShowerHandler.h"
#include "Herwig/Shower/ShowerHandler.h"
using namespace Herwig;
-ConstituentReshuffler::ConstituentReshuffler()
- : HandlerBase() {}
-
-ConstituentReshuffler::~ConstituentReshuffler() {}
-
IBPtr ConstituentReshuffler::clone() const {
return new_ptr(*this);
}
IBPtr ConstituentReshuffler::fullclone() const {
return new_ptr(*this);
}
void ConstituentReshuffler::reshuffle(PList& out,
PPair& in,
PList& intermediates,
const bool decay,
PList& decayPartons,
PList& decayRecoilers) {
assert(ShowerHandler::currentHandler()->retConstituentMasses());
if ( !decay ) {
if (out.size() == 0)
return;
if (out.size() == 1) {
PPtr recoiler;
PPtr parton = out.front();
if (DipolePartonSplitter::colourConnected(parton,in.first) &&
DipolePartonSplitter::colourConnected(parton,in.second)) {
if (UseRandom::rnd() < .5)
recoiler = in.first;
else
recoiler = in.second;
} else if (DipolePartonSplitter::colourConnected(parton,in.first)) {
recoiler = in.first;
} else if (DipolePartonSplitter::colourConnected(parton,in.second)) {
recoiler = in.second;
} else assert(false);
assert(abs(recoiler->momentum().vect().perp2()/GeV2) < 1e-6);
double sign = recoiler->momentum().z() < 0.*GeV ? -1. : 1.;
Energy2 qperp2 = parton->momentum().perp2();
if (qperp2/GeV2 < Constants::epsilon) {
// no emission off a 2 -> singlet process which
// needed a single forced splitting: should never happen (?)
assert(false);
throw Veto();
}
Energy2 m2 = sqr(parton->dataPtr()->constituentMass());
Energy abs_q = parton->momentum().vect().mag();
Energy qz = parton->momentum().z();
Energy abs_pz = recoiler->momentum().t();
assert(abs_pz > 0.*GeV);
Energy xi_pz = sign*(2.*qperp2*abs_pz + m2*(abs_q + sign*qz))/(2.*qperp2);
Energy x_qz = (2.*qperp2*qz + m2*(qz+sign*abs_q))/(2.*qperp2);
Lorentz5Momentum recoiler_momentum
(0.*GeV,0.*GeV,xi_pz,xi_pz < 0.*GeV ? - xi_pz : xi_pz);
recoiler_momentum.rescaleMass();
Lorentz5Momentum parton_momentum
(parton->momentum().x(),parton->momentum().y(),x_qz,sqrt(m2+qperp2+x_qz*x_qz));
parton_momentum.rescaleMass();
PPtr n_parton = new_ptr(Particle(parton->dataPtr()));
n_parton->set5Momentum(parton_momentum);
DipolePartonSplitter::change(parton,n_parton,false);
out.pop_front();
intermediates.push_back(parton);
out.push_back(n_parton);
PPtr n_recoiler = new_ptr(Particle(recoiler->dataPtr()));
n_recoiler->set5Momentum(recoiler_momentum);
DipolePartonSplitter::change(recoiler,n_recoiler,true);
intermediates.push_back(recoiler);
if (recoiler == in.first) {
in.first = n_recoiler;
}
if (recoiler == in.second) {
in.second = n_recoiler;
}
return;
}
}
Energy zero (0.*GeV);
Lorentz5Momentum Q (zero,zero,zero,zero);
for (PList::iterator p = out.begin();
p != out.end(); ++p) {
Q += (**p).momentum();
}
Boost beta = Q.findBoostToCM();
list<Lorentz5Momentum> mbackup;
bool need_boost = (beta.mag2() > Constants::epsilon);
if (need_boost) {
for (PList::iterator p = out.begin();
p != out.end(); ++p) {
Lorentz5Momentum mom = (**p).momentum();
mbackup.push_back(mom);
(**p).set5Momentum(mom.boost(beta));
}
}
double xi;
// Only partons
if ( decayRecoilers.size()==0 ) {
list<Energy> masses;
for ( auto p : out )
masses.push_back(p->dataPtr()->constituentMass());
ReshuffleEquation<PList::iterator,list<Energy>::const_iterator>
solve (Q.m(),out.begin(),out.end(),
masses.begin(),masses.end());
GSLBisection solver(1e-10,1e-8,10000);
try {
xi = solver.value(solve,0.0,1.1);
} catch (GSLBisection::GSLerror) {
throw DipoleShowerHandler::RedoShower();
} catch (GSLBisection::IntervalError) {
throw DipoleShowerHandler::RedoShower();
}
}
// Partons and decaying recoilers
else {
DecayReshuffleEquation solve (Q.m(),decayPartons.begin(),decayPartons.end(),decayRecoilers.begin(),decayRecoilers.end());
GSLBisection solver(1e-10,1e-8,10000);
try {
xi = solver.value(solve,0.0,1.1);
} catch (GSLBisection::GSLerror) {
throw DipoleShowerHandler::RedoShower();
} catch (GSLBisection::IntervalError) {
throw DipoleShowerHandler::RedoShower();
}
}
PList reshuffled;
list<Lorentz5Momentum>::const_iterator backup_it;
if (need_boost)
backup_it = mbackup.begin();
// Reshuffling of non-decaying partons only
if ( decayRecoilers.size()==0 ) {
for (PList::iterator p = out.begin();
p != out.end(); ++p) {
PPtr rp = new_ptr(Particle((**p).dataPtr()));
DipolePartonSplitter::change(*p,rp,false);
Lorentz5Momentum rm;
rm = Lorentz5Momentum (xi*(**p).momentum().x(),
xi*(**p).momentum().y(),
xi*(**p).momentum().z(),
sqrt(sqr((**p).dataPtr()->constituentMass()) +
xi*xi*(sqr((**p).momentum().t())-sqr((**p).dataPtr()->mass()))));
rm.rescaleMass();
if (need_boost) {
(**p).set5Momentum(*backup_it);
++backup_it;
rm.boost(-beta);
}
rp->set5Momentum(rm);
intermediates.push_back(*p);
reshuffled.push_back(rp);
}
}
// For the case of a decay process with non-partonic recoilers
else {
assert ( decay );
for (PList::iterator p = out.begin();
p != out.end(); ++p) {
// Flag to update spinInfo
bool updateSpin = false;
PPtr rp = new_ptr(Particle((**p).dataPtr()));
DipolePartonSplitter::change(*p,rp,false);
Lorentz5Momentum rm;
// If the particle is a parton and not a recoiler
if ( find( decayRecoilers.begin(), decayRecoilers.end(), *p ) == decayRecoilers.end() ) {
rm = Lorentz5Momentum (xi*(**p).momentum().x(),
xi*(**p).momentum().y(),
xi*(**p).momentum().z(),
sqrt(sqr((**p).dataPtr()->constituentMass()) +
xi*xi*(sqr((**p).momentum().t())-sqr((**p).dataPtr()->mass()))));
}
// Otherwise the parton is a recoiler
// and its invariant mass must be preserved
else {
if ( (*p)-> spinInfo() )
updateSpin = true;
rm = Lorentz5Momentum (xi*(**p).momentum().x(),
xi*(**p).momentum().y(),
xi*(**p).momentum().z(),
sqrt(sqr((**p).momentum().m()) +
xi*xi*(sqr((**p).momentum().t())-sqr((**p).momentum().m()))));
}
rm.rescaleMass();
if (need_boost) {
(**p).set5Momentum(*backup_it);
++backup_it;
rm.boost(-beta);
}
rp->set5Momentum(rm);
// Update SpinInfo if required
if ( updateSpin )
updateSpinInfo(*p, rp);
intermediates.push_back(*p);
reshuffled.push_back(rp);
}
}
out.clear();
out.splice(out.end(),reshuffled);
}
void ConstituentReshuffler::hardProcDecayReshuffle(PList& decaying,
PList& eventOutgoing,
PList& eventHard,
PPair& eventIncoming,
PList& eventIntermediates) {
// Note, when this function is called, the particle pointers
// in theDecays/decaying are those prior to the showering.
// Here we find the newest pointers in the outgoing.
// The update of the PPtrs in theDecays is done in DipoleShowerHandler::constituentReshuffle()
// as this needs to be done if ConstituentReshuffling is switched off.
//Make sure the shower should return constituent masses:
assert(ShowerHandler::currentHandler()->retConstituentMasses());
// Find the outgoing decaying particles
PList recoilers;
for ( PList::iterator decIt = decaying.begin(); decIt != decaying.end(); ++decIt) {
// First find the particles in the intermediates
PList::iterator pos = find(eventIntermediates.begin(),eventIntermediates.end(), *decIt);
// Colourless particle or coloured particle that did not radiate.
if(pos==eventIntermediates.end()) {
// Check that this is not a particle from a subsequent decay.
// e.g. the W from a top decay from an LHE file.
if ( find( eventHard.begin(), eventHard.end(), *decIt ) == eventHard.end() &&
find( eventOutgoing.begin(), eventOutgoing.end(), *decIt ) == eventOutgoing.end() )
continue;
else
recoilers.push_back( *decIt );
}
// Coloured decaying particle that radiated
else {
PPtr unstable = *pos;
while(!unstable->children().empty()) {
unstable = unstable->children()[0];
}
assert( find( eventOutgoing.begin(),eventOutgoing.end(), unstable ) != eventOutgoing.end() );
recoilers.push_back( unstable );
}
}
// Make a list of partons
PList partons;
for ( PList::iterator outPos = eventOutgoing.begin(); outPos != eventOutgoing.end(); ++outPos ) {
if ( find (recoilers.begin(), recoilers.end(), *outPos ) == recoilers.end() ) {
partons.push_back( *outPos );
}
}
// If no outgoing partons, do nothing
if ( partons.size() == 0 ){
return;
}
// Otherwise reshuffling needs to be done.
// If there is only one parton, attempt to reshuffle with
// the incoming to be consistent with the reshuffle for a
// hard process with no decays.
else if ( partons.size() == 1 &&
( DipolePartonSplitter::colourConnected(partons.front(),eventIncoming.first) ||
DipolePartonSplitter::colourConnected(partons.front(),eventIncoming.second) ) ) {
// Erase the parton from the event outgoing
eventOutgoing.erase( find( eventOutgoing.begin(), eventOutgoing.end(), partons.front() ) );
// Perform the reshuffle, this update the intermediates and the incoming
reshuffle(partons, eventIncoming, eventIntermediates);
// Update the outgoing
eventOutgoing.push_back(partons.front());
return;
}
// If reshuffling amongst the incoming is not possible
// or if we have multiple outgoing partons.
else {
// Create a complete list of the outgoing from the process
PList out;
// Make an empty list for storing the new intermediates
PList intermediates;
// Empty incoming particles pair
PPair in;
// A single parton which cannot be reshuffled
// with the incoming.
if ( partons.size() == 1 ) {
// Populate the out for the reshuffling
out.insert(out.end(),partons.begin(),partons.end());
out.insert(out.end(),recoilers.begin(),recoilers.end());
assert( out.size() > 1 );
// Perform the reshuffle with the temporary particle lists
reshuffle(out, in, intermediates, true, partons, recoilers);
}
// If there is more than one parton, reshuffle only
// amongst the partons
else {
assert(partons.size() > 1);
// Populate the out for the reshuffling
out.insert(out.end(),partons.begin(),partons.end());
assert( out.size() > 1 );
// Perform the reshuffle with the temporary particle lists
reshuffle(out, in, intermediates, true);
}
// Update the dipole event record
updateEvent(intermediates, eventIntermediates, out, eventOutgoing, eventHard );
return;
}
}
void ConstituentReshuffler::decayReshuffle(PerturbativeProcessPtr& decayProc,
PList& eventOutgoing,
PList& eventHard,
PList& eventIntermediates ) {
// Separate particles into those to be assigned constituent masses
// i.e. non-decaying coloured partons
// and those which must only absorb recoil
// i.e. non-coloured and decaying particles
PList partons;
PList recoilers;
//Make sure the shower should return constituent masses:
assert(ShowerHandler::currentHandler()->retConstituentMasses());
// Populate the particle lists from the outgoing of the decay process
for( unsigned int ix = 0; ix<decayProc->outgoing().size(); ++ix) {
// Identify recoilers
if ( !decayProc->outgoing()[ix].first->coloured() ||
ShowerHandler::currentHandler()->decaysInShower(decayProc->outgoing()[ix].first->id() ) )
recoilers.push_back(decayProc->outgoing()[ix].first);
else
partons.push_back(decayProc->outgoing()[ix].first);
}
// If there are no outgoing partons, then no reshuffling
// needs to be done
if ( partons.size() == 0 )
return;
// Reshuffling needs to be done:
else {
// Create a complete list of the outgoing from the process
PList out;
// Make an empty list for storing the new intermediates
PList intermediates;
// Empty incoming particles pair
PPair in;
// SW - 15/06/2018, 31/01/2019 - Always include 'recoilers' in
// reshuffling, regardless of the number of partons to be put on their
// constituent mass shell. This is because reshuffling between 2 partons
// frequently leads to a redoShower exception. This treatment is
// consistent with the AO shower
// Populate the out for the reshuffling
out.insert(out.end(),partons.begin(),partons.end());
out.insert(out.end(),recoilers.begin(),recoilers.end());
assert( out.size() > 1 );
// Perform the reshuffle with the temporary particle lists
reshuffle(out, in, intermediates, true, partons, recoilers);
// Update the dipole event record and the decay process
updateEvent(intermediates, eventIntermediates, out, eventOutgoing, eventHard, decayProc );
return;
}
}
void ConstituentReshuffler::updateEvent( PList& intermediates,
PList& eventIntermediates,
#ifndef NDEBUG
PList& out,
#else
PList&,
#endif
PList& eventOutgoing,
PList& eventHard,
PerturbativeProcessPtr decayProc ) {
// Loop over the new intermediates following the reshuffling
for (PList::iterator p = intermediates.begin();
p != intermediates.end(); ++p) {
// Update the event record intermediates
eventIntermediates.push_back(*p);
// Identify the reshuffled particle
assert( (*p)->children().size()==1 );
PPtr reshuffled = (*p)->children()[0];
assert( find(out.begin(), out.end(), reshuffled) != out.end() );
// Update the event record outgoing
PList::iterator posOut = find(eventOutgoing.begin(), eventOutgoing.end(), *p);
if ( posOut != eventOutgoing.end() ) {
eventOutgoing.erase(posOut);
eventOutgoing.push_back(reshuffled);
}
else {
PList::iterator posHard = find(eventHard.begin(), eventHard.end(), *p);
assert( posHard != eventHard.end() );
eventHard.erase(posHard);
eventHard.push_back(reshuffled);
}
// Replace the particle in the the decay process outgoing
if ( decayProc ) {
vector<pair<PPtr,PerturbativeProcessPtr> >::iterator decayOutIt = decayProc->outgoing().end();
for ( decayOutIt = decayProc->outgoing().begin();
decayOutIt!= decayProc->outgoing().end(); ++decayOutIt ) {
if ( decayOutIt->first == *p ){
break;
}
}
assert( decayOutIt != decayProc->outgoing().end() );
decayOutIt->first = reshuffled;
}
}
}
void ConstituentReshuffler::updateSpinInfo( PPtr& oldPart,
PPtr& newPart ) {
const Lorentz5Momentum& oldMom = oldPart->momentum();
const Lorentz5Momentum& newMom = newPart->momentum();
// Rotation from old momentum to +ve z-axis
LorentzRotation oldToZAxis;
Axis axisOld(oldMom.vect().unit());
if( axisOld.perp2() > 1e-12 ) {
double sinth(sqrt(1.-sqr(axisOld.z())));
oldToZAxis.rotate( -acos(axisOld.z()),Axis(-axisOld.y()/sinth,axisOld.x()/sinth,0.));
}
// Rotation from new momentum to +ve z-axis
LorentzRotation newToZAxis;
Axis axisNew(newMom.vect().unit());
if( axisNew.perp2() > 1e-12 ) {
double sinth(sqrt(1.-sqr(axisNew.z())));
newToZAxis.rotate( -acos(axisNew.z()),Axis(-axisNew.y()/sinth,axisNew.x()/sinth,0.));
}
// Boost from old momentum to new momentum along z-axis
Lorentz5Momentum momOldRotated = oldToZAxis*Lorentz5Momentum(oldMom);
Lorentz5Momentum momNewRotated = newToZAxis*Lorentz5Momentum(newMom);
Energy2 a = sqr(momOldRotated.z()) + sqr(momNewRotated.t());
Energy2 b = 2.*momOldRotated.t()*momOldRotated.z();
Energy2 c = sqr(momOldRotated.t()) - sqr(momNewRotated.t());
double beta;
// The rotated momentum should always lie along the +ve z-axis
if ( momOldRotated.z() > ZERO )
beta = (-b + sqrt(sqr(b)-4.*a*c)) / 2. / a;
else
beta = (-b - sqrt(sqr(b)-4.*a*c)) / 2. / a;
LorentzRotation boostOldToNew(0., 0., beta);
// Total transform
LorentzRotation transform = (newToZAxis.inverse())*boostOldToNew*oldToZAxis;
// Assign the same spin info to the old and new particles
newPart->spinInfo(oldPart->spinInfo());
newPart->spinInfo()->transform(oldMom, transform);
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void ConstituentReshuffler::persistentOutput(PersistentOStream &) const {
}
void ConstituentReshuffler::persistentInput(PersistentIStream &, int) {
}
ClassDescription<ConstituentReshuffler> ConstituentReshuffler::initConstituentReshuffler;
// Definition of the static class description member.
void ConstituentReshuffler::Init() {
static ClassDocumentation<ConstituentReshuffler> documentation
("The ConstituentReshuffler class implements reshuffling "
"of partons on their nominal mass shell to their constituent "
"mass shells.");
}
diff --git a/Shower/Dipole/Utility/ConstituentReshuffler.h b/Shower/Dipole/Utility/ConstituentReshuffler.h
--- a/Shower/Dipole/Utility/ConstituentReshuffler.h
+++ b/Shower/Dipole/Utility/ConstituentReshuffler.h
@@ -1,274 +1,259 @@
// -*- C++ -*-
//
// ConstituentReshuffler.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_ConstituentReshuffler_H
#define HERWIG_ConstituentReshuffler_H
//
// This is the declaration of the ConstituentReshuffler class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Utilities/Exception.h"
#include "Herwig/Shower/PerturbativeProcess.h"
#include "Herwig/Utilities/Reshuffler.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer, Stephen Webster
*
* \brief The ConstituentReshuffler class implements reshuffling
* of partons on their nominal mass shell to their constituent
* mass shells.
*
*/
class ConstituentReshuffler: public HandlerBase, public Reshuffler {
public:
- /** @name Standard constructors and destructors. */
- //@{
- /**
- * The default constructor.
- */
- ConstituentReshuffler();
-
- /**
- * The destructor.
- */
- virtual ~ConstituentReshuffler();
- //@}
-
-public:
-
/**
* Reshuffle the outgoing partons to constituent
* masses. Optionally, incoming partons are given
* to absorb recoils. Add the non-reshuffled partons
* to the intermediates list. Throw ConstituentReshufflerProblem
* if a numerical problem prevents the solution of
* the reshuffling equation.
*/
void reshuffle(PList& out,
PPair& in,
PList& intermediates,
const bool decay,
PList& decayPartons,
PList& decayRecoilers);
/**
* Reshuffle the outgoing partons to constituent
* masses. Optionally, incoming partons are given
* to absorb recoils. Add the non-reshuffled partons
* to the intermediates list. Throw ConstituentReshufflerProblem
* if a numerical problem prevents the solution of
* the reshuffling equation.
*/
void reshuffle(PList& out,
PPair& in,
PList& intermediates,
const bool decay=false) {
PList decayPartons;
PList decayRecoilers;
reshuffle(out,
in,
intermediates,
decay,
decayPartons,
decayRecoilers);
}
/**
* Reshuffle the outgoing partons following the showering
* of the initial hard interaction to constituent masses,
* for the case of outgoing decaying particles.
* Throw ConstituentReshufflerProblem
* if a numerical problem prevents the solution of
* the reshuffling equation.
*/
void hardProcDecayReshuffle(PList& decaying,
PList& eventOutgoing,
PList& eventHard,
PPair& eventIncoming,
PList& eventIntermediates) ;
/**
* Reshuffle the outgoing partons following the showering
* of a particle decay to constituent masses.
* Throw ConstituentReshufflerProblem
* if a numerical problem prevents the solution of
* the reshuffling equation.
*/
void decayReshuffle(PerturbativeProcessPtr& decayProc,
PList& eventOutgoing,
PList& eventHard,
PList& eventIntermediates) ;
/**
* Update the dipole event record and, if appropriate,
* the relevant decay process.
**/
void updateEvent( PList& intermediates,
PList& eventIntermediates,
PList& out,
PList& eventOutgoing,
PList& eventHard,
PerturbativeProcessPtr decayProc = PerturbativeProcessPtr() ) ;
/**
* Update the spinInfo of a particle following reshuffling
* to take account of the change in momentum.
* Used only for unstable particles that need to be dealt with.
**/
void updateSpinInfo( PPtr& oldPart,
PPtr& newPart ) ;
protected:
/**
* The function object defining the equation
* to be solved in the case of separate recoilers
* TODO - refine the whole implementation of separate partons and recoilers
*/
struct DecayReshuffleEquation {
DecayReshuffleEquation (Energy q,
PList::iterator m_begin,
PList::iterator m_end,
PList::iterator n_begin,
PList::iterator n_end)
: w(q), p_begin(m_begin), p_end(m_end), r_begin(n_begin), r_end(n_end) {}
typedef double ArgType;
typedef double ValType;
static double aUnit();
static double vUnit();
double operator() (double xi) const;
Energy w;
PList::iterator p_begin;
PList::iterator p_end;
PList::iterator r_begin;
PList::iterator r_end;
};
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 static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<ConstituentReshuffler> initConstituentReshuffler;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
ConstituentReshuffler & operator=(const ConstituentReshuffler &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of ConstituentReshuffler. */
template <>
struct BaseClassTrait<Herwig::ConstituentReshuffler,1> {
/** Typedef of the first base class of ConstituentReshuffler. */
typedef HandlerBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the ConstituentReshuffler class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::ConstituentReshuffler>
: public ClassTraitsBase<Herwig::ConstituentReshuffler> {
/** Return a platform-independent class name */
static string className() { return "Herwig::ConstituentReshuffler"; }
/**
* The name of a file containing the dynamic library where the class
* ConstituentReshuffler is implemented. It may also include several, space-separated,
* libraries if the class ConstituentReshuffler 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_ConstituentReshuffler_H */
diff --git a/Shower/Dipole/Utility/DipoleMCCheck.cc b/Shower/Dipole/Utility/DipoleMCCheck.cc
--- a/Shower/Dipole/Utility/DipoleMCCheck.cc
+++ b/Shower/Dipole/Utility/DipoleMCCheck.cc
@@ -1,283 +1,281 @@
// -*- C++ -*-
//
// DipoleMCCheck.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 DipoleMCCheck class.
//
#include "DipoleMCCheck.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
DipoleMCCheck::DipoleMCCheck()
: HandlerBase(),
theHardPtBins(10),
theEmitterXBins(5), theSpectatorXBins(5),
thePtBins(100), theZBins(100) {
}
-DipoleMCCheck::~DipoleMCCheck() {}
-
IBPtr DipoleMCCheck::clone() const {
return new_ptr(*this);
}
IBPtr DipoleMCCheck::fullclone() const {
return new_ptr(*this);
}
vector<double> DipoleMCCheck::makeLogBins(double xlow, double xup, unsigned int n) const {
vector<double> res;
double c = log10(xup/xlow) / (n-1.);
for ( unsigned int k = 0; k < n; ++k )
res.push_back(xlow*pow(10.0,k*c));
return res;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void DipoleMCCheck::doinitrun() {
HandlerBase::doinitrun();
vector<double> ptbins;
double w = 0.5/theHardPtBins;
for ( unsigned int k = 1; k <= theHardPtBins; ++k )
ptbins.push_back(k*w);
vector<double> xebins;
if ( theEmitterXBins > 1 )
xebins = makeLogBins(1e-7,1.0,theEmitterXBins);
else
xebins.push_back(1.0);
vector<double> xsbins;
if ( theSpectatorXBins > 1 )
xsbins = makeLogBins(1e-7,1.0,theSpectatorXBins);
else
xsbins.push_back(1.0);
for ( vector<double>::const_iterator xeit = xebins.begin();
xeit != xebins.end(); ++xeit ) {
map<double,
map<double,
pair<Ptr<Histogram>::ptr,Ptr<Histogram>::ptr>
>
> xebin;
for ( vector<double>::const_iterator xsit = xsbins.begin();
xsit != xsbins.end(); ++xsit ) {
map<double,
pair<Ptr<Histogram>::ptr,Ptr<Histogram>::ptr>
> xsbin;
for ( vector<double>::const_iterator ptit = ptbins.begin();
ptit != ptbins.end(); ++ptit ) {
pair<Ptr<Histogram>::ptr,Ptr<Histogram>::ptr> ptbin
(new_ptr(Histogram(0.0,0.5,thePtBins)),
new_ptr(Histogram(0.0,1.0,theZBins)));
xsbin[*ptit] = ptbin;
}
xebin[*xsit] = xsbin;
}
histoMap[*xeit] = xebin;
}
}
void DipoleMCCheck::dofinish() {
HandlerBase::dofinish();
map<double,
map<double,
map<double,
pair<Ptr<Histogram>::ptr,Ptr<Histogram>::ptr>
>
>
>::iterator xeit;
map<double,
map<double,
pair<Ptr<Histogram>::ptr,Ptr<Histogram>::ptr>
>
>::iterator xsit;
map<double,
pair<Ptr<Histogram>::ptr,Ptr<Histogram>::ptr>
>::iterator ptit;
double xelow = 0.0;
double xeup = 0.0;
for ( xeit = histoMap.begin(); xeit != histoMap.end(); ++xeit ) {
xeup = xelow + xeit->first;
double xslow = 0.0;
double xsup = 0.0;
for ( xsit = xeit->second.begin(); xsit != xeit->second.end(); ++xsit ) {
xsup = xslow + xsit->first;
// open files here
ostringstream ptFileName;
ptFileName << name() << "_pt_"
<< xelow << "_" << xeup << "_"
<< xslow << "_" << xsup << ".dat";
ofstream ptFile(ptFileName.str().c_str());
ostringstream zFileName;
zFileName << name() << "_z_"
<< xelow << "_" << xeup << "_"
<< xslow << "_" << xsup << ".dat";
ofstream zFile(zFileName.str().c_str());
double ptlow = 0.0;
double ptup = 0.0;
for ( ptit = xsit->second.begin(); ptit != xsit->second.end(); ++ptit ) {
ptup = ptlow + ptit->first;
// dump histos here
ptFile << "#\n# " << ptlow << " < \\kappa < " << ptup << "\n#\n";
zFile << "#\n# " << ptlow << " < \\kappa < " << ptup << "\n#\n";
ptit->second.first->simpleOutput(ptFile,false);
ptit->second.second->simpleOutput(zFile,false);
ptFile << "\n\n\n";
zFile << "\n\n\n";
ptlow = ptup;
}
xslow = xsup;
}
xelow = xeup;
}
}
void DipoleMCCheck::book(double xe,double xs,
Energy dScale,
Energy hardPt,
Energy pt, double z,
double weight) {
map<double,
map<double,
map<double,
pair<Ptr<Histogram>::ptr,Ptr<Histogram>::ptr>
>
>
>::iterator xeit;
map<double,
map<double,
pair<Ptr<Histogram>::ptr,Ptr<Histogram>::ptr>
>
>::iterator xsit;
map<double,
pair<Ptr<Histogram>::ptr,Ptr<Histogram>::ptr>
>::iterator ptit;
if ( theEmitterXBins == 1 || xe >= 1. )
xeit = --histoMap.end();
else
xeit = histoMap.upper_bound(xe);
if ( theSpectatorXBins == 1 || xs >= 1. )
xsit = --(xeit->second.end());
else
xsit = xeit->second.upper_bound(xs);
if ( theHardPtBins == 1 || hardPt/dScale >= 0.5 )
ptit = --(xsit->second.end());
else
ptit = xsit->second.upper_bound(hardPt/dScale);
ptit->second.first->addWeighted(pt/dScale,weight);
ptit->second.second->addWeighted(z,weight);
}
void DipoleMCCheck::persistentOutput(PersistentOStream & os) const {
os << theHardPtBins << theEmitterXBins
<< theSpectatorXBins << thePtBins
<< theZBins;
}
void DipoleMCCheck::persistentInput(PersistentIStream & is, int) {
is >> theHardPtBins >> theEmitterXBins
>> theSpectatorXBins >> thePtBins
>> theZBins;
}
ClassDescription<DipoleMCCheck> DipoleMCCheck::initDipoleMCCheck;
// Definition of the static class description member.
void DipoleMCCheck::Init() {
static ClassDocumentation<DipoleMCCheck> documentation
("DipoleMCCheck is used to perform checks for "
"the dipole shower.");
static Parameter<DipoleMCCheck,unsigned int> interfaceHardPtBins
("HardPtBins",
"HardPtBins",
&DipoleMCCheck::theHardPtBins, 10, 1, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleMCCheck,unsigned int> interfaceEmitterXBins
("EmitterXBins",
"EmitterXBins",
&DipoleMCCheck::theEmitterXBins, 5, 1, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleMCCheck,unsigned int> interfaceSpectatorXBins
("SpectatorXBins",
"SpectatorXBins",
&DipoleMCCheck::theSpectatorXBins, 5, 1, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleMCCheck,unsigned int> interfacePtBins
("PtBins",
"PtBins",
&DipoleMCCheck::thePtBins, 100, 1, 0,
false, false, Interface::lowerlim);
static Parameter<DipoleMCCheck,unsigned int> interfaceZBins
("ZBins",
"ZBins",
&DipoleMCCheck::theZBins, 100, 1, 0,
false, false, Interface::lowerlim);
}
diff --git a/Shower/Dipole/Utility/DipoleMCCheck.h b/Shower/Dipole/Utility/DipoleMCCheck.h
--- a/Shower/Dipole/Utility/DipoleMCCheck.h
+++ b/Shower/Dipole/Utility/DipoleMCCheck.h
@@ -1,231 +1,223 @@
// -*- C++ -*-
//
// DipoleMCCheck.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_DipoleMCCheck_H
#define HERWIG_DipoleMCCheck_H
//
// This is the declaration of the DipoleMCCheck class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "Herwig/Utilities/Histogram.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief DipoleMCCheck is used to perform checks for
* the dipole shower.
*
* @see \ref DipoleMCCheckInterfaces "The interfaces"
* defined for DipoleMCCheck.
*/
class DipoleMCCheck: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
DipoleMCCheck();
- /**
- * The destructor.
- */
- virtual ~DipoleMCCheck();
- //@}
-
public:
/**
* Book a point.
*/
void book(double xe,double xs,
Energy dScale,
Energy hardPt,
Energy pt, double z,
double weight);
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:
/**
* 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();
// If needed, insert declarations of virtual function defined in the
// InterfacedBase class here (using ThePEG-interfaced-decl in Emacs).
private:
/**
* The number of bins in the starting scale
* divided by the dipole scale, the upper bound
* is 1/2.
*/
unsigned int theHardPtBins;
/**
* The number of bins in the emitter fraction.
* The lenght of the zero bin is taken to be
* 10^(-7).
*/
unsigned int theEmitterXBins;
/**
* The number of bins in the spectator fraction.
* The lenght of the zero bin is taken to be
* 10^(-7).
*/
unsigned int theSpectatorXBins;
/**
* The number of bins in pt dicided by the
* dipole scale; the upper bound is 1/2
*/
unsigned int thePtBins;
/**
* The number of bins in z
*/
unsigned int theZBins;
/**
* The recursive map structure: xe, xs, hard pt / GeV
* to histograms for pt and z;
* output is done such that there's one file for each
* xe,xs bin, including all histograms for the
* hard pt bins.
*/
map<double,
map<double,
map<double,
pair<Ptr<Histogram>::ptr,Ptr<Histogram>::ptr>
>
>
> histoMap;
/**
* Helper to make logarithmic bins.
*/
vector<double> makeLogBins(double xlow, double xup, unsigned int n) const;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<DipoleMCCheck> initDipoleMCCheck;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
DipoleMCCheck & operator=(const DipoleMCCheck &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of DipoleMCCheck. */
template <>
struct BaseClassTrait<Herwig::DipoleMCCheck,1> {
/** Typedef of the first base class of DipoleMCCheck. */
typedef HandlerBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the DipoleMCCheck class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::DipoleMCCheck>
: public ClassTraitsBase<Herwig::DipoleMCCheck> {
/** Return a platform-independent class name */
static string className() { return "Herwig::DipoleMCCheck"; }
/**
* The name of a file containing the dynamic library where the class
* DipoleMCCheck is implemented. It may also include several, space-separated,
* libraries if the class DipoleMCCheck 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_DipoleMCCheck_H */
diff --git a/Shower/Dipole/Utility/IntrinsicPtGenerator.cc b/Shower/Dipole/Utility/IntrinsicPtGenerator.cc
--- a/Shower/Dipole/Utility/IntrinsicPtGenerator.cc
+++ b/Shower/Dipole/Utility/IntrinsicPtGenerator.cc
@@ -1,198 +1,196 @@
// -*- C++ -*-
//
// IntrinsicPtGenerator.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 IntrinsicPtGenerator class.
//
#include "IntrinsicPtGenerator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Config/Constants.h"
#include "DipolePartonSplitter.h"
#include "Herwig/Shower/ShowerHandler.h"
#include "Herwig/PDF/HwRemDecayer.h"
using namespace Herwig;
IntrinsicPtGenerator::IntrinsicPtGenerator()
: HandlerBase(),
theValenceIntrinsicPtScale(1.0*GeV),
theSeaIntrinsicPtScale(1.0*GeV) {}
-IntrinsicPtGenerator::~IntrinsicPtGenerator() {}
-
IBPtr IntrinsicPtGenerator::clone() const {
return new_ptr(*this);
}
IBPtr IntrinsicPtGenerator::fullclone() const {
return new_ptr(*this);
}
LorentzRotation IntrinsicPtGenerator::kick(PPair& in,
PList& intermediates) {
if ( theValenceIntrinsicPtScale == 0.0*GeV &&
theSeaIntrinsicPtScale == 0.0*GeV )
return LorentzRotation();
assert(ShowerHandler::currentHandler());
tHwRemDecPtr remDec = ShowerHandler::currentHandler()->remnantDecayer();
assert(remDec);
Lorentz5Momentum Q = in.first->momentum() + in.second->momentum();
// first parton
if (in.first->coloured()) {
Axis perp;
Energy pt = 0.*GeV;
double phi = 2.*Constants::pi*UseRandom::rnd();
Axis dir = in.first->momentum().vect().unit();
perp = dir.orthogonal();
perp.rotate(phi,dir);
double r = sqrt(-log(1.-UseRandom::rnd()));
if ( remDec->content().first.isValenceQuark(in.first) )
pt = sqrt(2.) * theValenceIntrinsicPtScale * r;
else {
assert(in.first->id() == ParticleID::g ||
remDec->content().first.isSeaQuark(in.first));
pt = sqrt(2.) * theSeaIntrinsicPtScale * r;
}
PPtr nin = new_ptr(Particle(in.first->dataPtr()));
DipolePartonSplitter::change(in.first,nin,true);
nin->set5Momentum(Lorentz5Momentum(0.*GeV,in.first->momentum().vect() +
pt * perp));
intermediates.push_back(in.first);
in.first = nin;
}
// second parton
if (in.second->coloured()) {
Axis perp;
Energy pt = 0.*GeV;
double phi = 2.*Constants::pi*UseRandom::rnd();
Axis dir = in.second->momentum().vect().unit();
perp = dir.orthogonal();
perp.rotate(phi,dir);
double r = sqrt(-log(1.-UseRandom::rnd()));
if ( remDec->content().second.isValenceQuark(in.second) )
pt = sqrt(2.) * theValenceIntrinsicPtScale * r;
else {
assert(in.second->id() == ParticleID::g ||
remDec->content().second.isSeaQuark(in.second));
pt = sqrt(2.) * theSeaIntrinsicPtScale * r;
}
PPtr nin = new_ptr(Particle(in.second->dataPtr()));
nin->colourInfo(new_ptr(ColourBase()));
DipolePartonSplitter::change(in.second,nin,true);
nin->set5Momentum(Lorentz5Momentum(0.*GeV,in.second->momentum().vect() +
pt * perp));
intermediates.push_back(in.second);
in.second = nin;
}
// restore mometum conservation
Lorentz5Momentum nQ = in.first->momentum() + in.second->momentum();
double x = Q.m()/nQ.m();
nQ *= x;
// work around for constructor problems
// in Lorentz5Vector constructor, mass is not guaranteed
// to be zero, event it was set as such before,
// since gets recalculated in the LorentzVector
Lorentz5Momentum scaled = x * in.first->momentum();
scaled.setMass(ZERO); scaled.rescaleEnergy();
in.first->set5Momentum(scaled);
scaled = x * in.second->momentum();
scaled.setMass(ZERO); scaled.rescaleEnergy();
in.second->set5Momentum(scaled);
// apparently, this is more stable than boosting directly with
// n_Q.boostVector()-Q.boostVector()
Boost beta1 = -Q.boostVector();
Boost beta2 = nQ.boostVector();
LorentzRotation transform (beta1);
transform.boost(beta2);
return transform;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void IntrinsicPtGenerator::persistentOutput(PersistentOStream & os) const {
os << ounit(theValenceIntrinsicPtScale,GeV) << ounit(theSeaIntrinsicPtScale,GeV);
}
void IntrinsicPtGenerator::persistentInput(PersistentIStream & is, int) {
is >> iunit(theValenceIntrinsicPtScale,GeV) >> iunit(theSeaIntrinsicPtScale,GeV);
}
ClassDescription<IntrinsicPtGenerator> IntrinsicPtGenerator::initIntrinsicPtGenerator;
// Definition of the static class description member.
void IntrinsicPtGenerator::Init() {
static ClassDocumentation<IntrinsicPtGenerator> documentation
("IntrinsicPtGenerator generates intrinsic pt for massless "
"incoming partons in a shower independent way.");
static Parameter<IntrinsicPtGenerator,Energy> interfaceValenceIntrinsicPtScale
("ValenceIntrinsicPtScale",
"The width of the intrinsic pt Gaussian distribution for valence partons.",
&IntrinsicPtGenerator::theValenceIntrinsicPtScale, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
static Parameter<IntrinsicPtGenerator,Energy> interfaceSeaIntrinsicPtScale
("SeaIntrinsicPtScale",
"The width of the intrinsic pt Gaussian distribution for sea partons.",
&IntrinsicPtGenerator::theSeaIntrinsicPtScale, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
}
diff --git a/Shower/Dipole/Utility/IntrinsicPtGenerator.h b/Shower/Dipole/Utility/IntrinsicPtGenerator.h
--- a/Shower/Dipole/Utility/IntrinsicPtGenerator.h
+++ b/Shower/Dipole/Utility/IntrinsicPtGenerator.h
@@ -1,174 +1,166 @@
// -*- C++ -*-
//
// IntrinsicPtGenerator.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_IntrinsicPtGenerator_H
#define HERWIG_IntrinsicPtGenerator_H
//
// This is the declaration of the IntrinsicPtGenerator class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/Vectors/LorentzRotation.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief IntrinsicPtGenerator generates intrinsic pt for massless
* incoming partons in a shower independent way.
*
* @see \ref IntrinsicPtGeneratorInterfaces "The interfaces"
* defined for IntrinsicPtGenerator.
*/
class IntrinsicPtGenerator: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
IntrinsicPtGenerator();
- /**
- * The destructor.
- */
- virtual ~IntrinsicPtGenerator();
- //@}
-
public:
/**
* Generate intrinsic pt for the given incoming
* partons and return the transformation to be
* applied on the final state particles. Add the
* old incoming partons to the given list.
*/
LorentzRotation kick(PPair& in,
PList& intermediates);
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 mean of the Gaussian distribution for
* the intrinsic pt of valence partons.
*/
Energy theValenceIntrinsicPtScale;
/**
* The mean of the Gaussian distribution for
* the intrinsic pt of sea partons.
*/
Energy theSeaIntrinsicPtScale;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<IntrinsicPtGenerator> initIntrinsicPtGenerator;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
IntrinsicPtGenerator & operator=(const IntrinsicPtGenerator &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of IntrinsicPtGenerator. */
template <>
struct BaseClassTrait<Herwig::IntrinsicPtGenerator,1> {
/** Typedef of the first base class of IntrinsicPtGenerator. */
typedef HandlerBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the IntrinsicPtGenerator class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::IntrinsicPtGenerator>
: public ClassTraitsBase<Herwig::IntrinsicPtGenerator> {
/** Return a platform-independent class name */
static string className() { return "Herwig::IntrinsicPtGenerator"; }
/**
* The name of a file containing the dynamic library where the class
* IntrinsicPtGenerator is implemented. It may also include several, space-separated,
* libraries if the class IntrinsicPtGenerator 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_IntrinsicPtGenerator_H */
diff --git a/Shower/Dipole/Utility/PDFRatio.cc b/Shower/Dipole/Utility/PDFRatio.cc
--- a/Shower/Dipole/Utility/PDFRatio.cc
+++ b/Shower/Dipole/Utility/PDFRatio.cc
@@ -1,144 +1,142 @@
// -*- C++ -*-
//
// PDFRatio.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 PDFRatio class.
//
#include "PDFRatio.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/Shower/ShowerHandler.h"
#include "Herwig/PDF/HwRemDecayer.h"
using namespace Herwig;
PDFRatio::PDFRatio()
: HandlerBase(),
theValenceExtrapolation(0.7), theSeaExtrapolation(0.6),
theFreezingScale(1.0*GeV) {}
-PDFRatio::~PDFRatio() {}
-
IBPtr PDFRatio::clone() const {
return new_ptr(*this);
}
IBPtr PDFRatio::fullclone() const {
return new_ptr(*this);
}
double PDFRatio::operator() (const PDF& pdf,
Energy2 scale,
tcPDPtr from, tcPDPtr to,
double x, double z) const {
if ( x/z > 1.0 )
return 0.0;
if(z==1)return 1.0;
if ( scale < sqr(theFreezingScale) )
scale = sqr(theFreezingScale);
tcHwRemDecPtr remDec =
ShowerHandler::currentHandler()->remnantDecayer();
const HwRemDecayer::HadronContent* theContent = 0;
if ( remDec->content().first.hadron == pdf.particle() ) {
theContent = &(remDec->content().first);
}
if ( remDec->content().second.hadron == pdf.particle() ) {
theContent = &(remDec->content().second);
}
assert(theContent);
double exFrom =
theContent->isValenceQuarkData(from) ?
theValenceExtrapolation : theSeaExtrapolation;
double exTo =
theContent->isValenceQuarkData(to) ?
theValenceExtrapolation : theSeaExtrapolation;
double xTo = x/z;
double fromPDF =
x < exFrom ?
pdf.xfx(from,scale,x) :
((1.-x)/(1.-exFrom)) * pdf.xfx(from,scale,exFrom);
if ( fromPDF < 1e-8 )
fromPDF = 0.0;
double toPDF =
xTo < exTo ?
pdf.xfx(to,scale,xTo) :
((1.-xTo)/(1.-exTo)) * pdf.xfx(to,scale,exTo);
if ( toPDF < 1e-8 )
toPDF = 0.0;
if ( toPDF == 0.0 || fromPDF == 0.0 )
return 0.0;
return toPDF / fromPDF;
}
// If needed, insert default implementations of virtual function defined
// in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs).
void PDFRatio::persistentOutput(PersistentOStream & os) const {
os << theValenceExtrapolation << theSeaExtrapolation
<< ounit(theFreezingScale,GeV);
}
void PDFRatio::persistentInput(PersistentIStream & is, int) {
is >> theValenceExtrapolation >> theSeaExtrapolation
>> iunit(theFreezingScale,GeV);
}
ClassDescription<PDFRatio> PDFRatio::initPDFRatio;
// Definition of the static class description member.
void PDFRatio::Init() {
static ClassDocumentation<PDFRatio> documentation
("PDFRatio implements numerically stable pdf ratios.");
static Parameter<PDFRatio,double> interfaceValenceExtrapolation
("ValenceExtrapolation",
"The x from which on extrapolation should be done for valence partons.",
&PDFRatio::theValenceExtrapolation, 0.7, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<PDFRatio,double> interfaceSeaExtrapolation
("SeaExtrapolation",
"The x from which on extrapolation should be done for valence partons.",
&PDFRatio::theSeaExtrapolation, 0.6, 0.0, 1.0,
false, false, Interface::limited);
static Parameter<PDFRatio,Energy> interfaceFreezingScale
("FreezingScale",
"The scale below which the PDFs are frozen.",
&PDFRatio::theFreezingScale, GeV, 1.0*GeV, 0.0*GeV, 0*GeV,
false, false, Interface::lowerlim);
}
diff --git a/Shower/Dipole/Utility/PDFRatio.h b/Shower/Dipole/Utility/PDFRatio.h
--- a/Shower/Dipole/Utility/PDFRatio.h
+++ b/Shower/Dipole/Utility/PDFRatio.h
@@ -1,178 +1,170 @@
// -*- C++ -*-
//
// PDFRatio.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_PDFRatio_H
#define HERWIG_PDFRatio_H
//
// This is the declaration of the PDFRatio class.
//
#include "ThePEG/Handlers/HandlerBase.h"
#include "ThePEG/PDF/PDF.h"
namespace Herwig {
using namespace ThePEG;
/**
* \ingroup DipoleShower
* \author Simon Platzer
*
* \brief PDFRatio implements numerically stable PDF ratios.
*
* @see \ref PDFRatioInterfaces "The interfaces"
* defined for PDFRatio.
*/
class PDFRatio: public HandlerBase {
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
PDFRatio();
- /**
- * The destructor.
- */
- virtual ~PDFRatio();
- //@}
-
public:
/**
* For the given PDF, scale and partons from and to and
* x,z values return the ratio xf_to(x/z) / xf_from(x)
*/
double operator() (const PDF& pdf,
Energy2 scale,
tcPDPtr from, tcPDPtr to,
double x, double z) 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 x from which on extrapolation should
* be done for valence partons.
*/
double theValenceExtrapolation;
/**
* The x from which on extrapolation should
* be done for sea partons.
*/
double theSeaExtrapolation;
/**
* The scale below which the PDF will be frozen
*/
Energy theFreezingScale;
private:
/**
* The static object used to initialize the description of this class.
* Indicates that this is a concrete class with persistent data.
*/
static ClassDescription<PDFRatio> initPDFRatio;
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
PDFRatio & operator=(const PDFRatio &) = delete;
};
}
#include "ThePEG/Utilities/ClassTraits.h"
namespace ThePEG {
/** @cond TRAITSPECIALIZATIONS */
/** This template specialization informs ThePEG about the
* base classes of PDFRatio. */
template <>
struct BaseClassTrait<Herwig::PDFRatio,1> {
/** Typedef of the first base class of PDFRatio. */
typedef HandlerBase NthBase;
};
/** This template specialization informs ThePEG about the name of
* the PDFRatio class and the shared object where it is defined. */
template <>
struct ClassTraits<Herwig::PDFRatio>
: public ClassTraitsBase<Herwig::PDFRatio> {
/** Return a platform-independent class name */
static string className() { return "Herwig::PDFRatio"; }
/**
* The name of a file containing the dynamic library where the class
* PDFRatio is implemented. It may also include several, space-separated,
* libraries if the class PDFRatio 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_PDFRatio_H */
diff --git a/Shower/QTilde/Base/PartnerFinder.cc b/Shower/QTilde/Base/PartnerFinder.cc
--- a/Shower/QTilde/Base/PartnerFinder.cc
+++ b/Shower/QTilde/Base/PartnerFinder.cc
@@ -1,699 +1,699 @@
// -*- C++ -*-
//
// PartnerFinder.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 PartnerFinder class.
//
#include "PartnerFinder.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/Shower/QTilde/Base/ShowerParticle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Utilities/Debug.h"
#include "ThePEG/Utilities/DescribeClass.h"
using namespace Herwig;
DescribeClass<PartnerFinder,Interfaced>
describePartnerFinder ("Herwig::PartnerFinder","HwShower.so");
// some useful functions to avoid using #define
namespace {
// return bool if final-state particle
inline bool FS(const tShowerParticlePtr a) {
return a->isFinalState();
}
// return colour line pointer
inline Ptr<ThePEG::ColourLine>::transient_pointer
CL(const tShowerParticlePtr a, unsigned int index=0) {
return a->colourInfo()->colourLines().empty() ? ThePEG::tColinePtr() :
const_ptr_cast<ThePEG::tColinePtr>(a->colourInfo()->colourLines()[index]);
}
// return colour line size
inline size_t
CLSIZE(const tShowerParticlePtr a) {
return a->colourInfo()->colourLines().size();
}
inline Ptr<ThePEG::ColourLine>::transient_pointer
ACL(const tShowerParticlePtr a, unsigned int index=0) {
return a->colourInfo()->antiColourLines().empty() ? ThePEG::tColinePtr() :
const_ptr_cast<ThePEG::tColinePtr>(a->colourInfo()->antiColourLines()[index]);
}
inline size_t
ACLSIZE(const tShowerParticlePtr a) {
return a->colourInfo()->antiColourLines().size();
}
}
void PartnerFinder::persistentOutput(PersistentOStream & os) const {
os << partnerMethod_ << QEDPartner_ << scaleChoice_;
}
void PartnerFinder::persistentInput(PersistentIStream & is, int) {
is >> partnerMethod_ >> QEDPartner_ >> scaleChoice_;
}
void PartnerFinder::Init() {
static ClassDocumentation<PartnerFinder> documentation
("This class is responsible for finding the partners for each interaction types ",
"and within the evolution scale range specified by the ShowerVariables ",
"then to determine the initial evolution scales for each pair of partners.");
static Switch<PartnerFinder,int> interfacePartnerMethod
("PartnerMethod",
"Choice of partner finding method for gluon evolution.",
&PartnerFinder::partnerMethod_, 0, false, false);
static SwitchOption interfacePartnerMethodRandom
(interfacePartnerMethod,
"Random",
"Choose partners of a gluon randomly.",
0);
static SwitchOption interfacePartnerMethodMaximum
(interfacePartnerMethod,
"Maximum",
"Choose partner of gluon with largest angle.",
1);
static Switch<PartnerFinder,int> interfaceQEDPartner
("QEDPartner",
"Control of which particles to use as the partner for QED radiation",
&PartnerFinder::QEDPartner_, 0, false, false);
static SwitchOption interfaceQEDPartnerAll
(interfaceQEDPartner,
"All",
"Consider all possible choices which give a positive contribution"
" in the soft limit.",
0);
static SwitchOption interfaceQEDPartnerIIandFF
(interfaceQEDPartner,
"IIandFF",
"Only allow initial-initial or final-final combinations",
1);
static SwitchOption interfaceQEDPartnerIF
(interfaceQEDPartner,
"IF",
"Only allow initial-final combinations",
2);
static Switch<PartnerFinder,int> interfaceScaleChoice
("ScaleChoice",
"The choice of the evolution scales",
&PartnerFinder::scaleChoice_, 0, false, false);
static SwitchOption interfaceScaleChoicePartner
(interfaceScaleChoice,
"Partner",
"Scale of all interactions is that of the evolution partner",
0);
static SwitchOption interfaceScaleChoiceDifferent
(interfaceScaleChoice,
"Different",
"Allow each interaction to have different scales",
1);
}
void PartnerFinder::setInitialEvolutionScales(const ShowerParticleVector &particles,
const bool isDecayCase,
ShowerInteraction type,
const bool setPartners) {
// clear the existing partners
for(ShowerParticleVector::const_iterator cit = particles.begin();
cit != particles.end(); ++cit) (*cit)->clearPartners();
// set them
if(type==ShowerInteraction::QCD) {
setInitialQCDEvolutionScales(particles,isDecayCase,setPartners);
}
else if(type==ShowerInteraction::QED) {
setInitialQEDEvolutionScales(particles,isDecayCase,setPartners);
}
else if(type==ShowerInteraction::EW) {
setInitialEWEvolutionScales(particles,isDecayCase,false);
}
else if(type==ShowerInteraction::QEDQCD) {
setInitialQCDEvolutionScales(particles,isDecayCase,setPartners);
setInitialQEDEvolutionScales(particles,isDecayCase,false);
}
else if(type==ShowerInteraction::ALL) {
setInitialQCDEvolutionScales(particles,isDecayCase,setPartners);
setInitialQEDEvolutionScales(particles,isDecayCase,false);
setInitialEWEvolutionScales(particles,isDecayCase,false);
}
else
assert(false);
// \todo EW scales here
// print out for debugging
if(Debug::level>=10) {
for(ShowerParticleVector::const_iterator cit = particles.begin();
cit != particles.end(); ++cit) {
generator()->log() << "Particle: " << **cit << "\n";
if(!(**cit).partner()) continue;
generator()->log() << "Primary partner: " << *(**cit).partner() << "\n";
for(vector<ShowerParticle::EvolutionPartner>::const_iterator it= (**cit).partners().begin();
it!=(**cit).partners().end();++it) {
generator()->log() << static_cast<long>(it->type) << " "
<< it->weight << " "
<< it->scale/GeV << " "
<< *(it->partner)
<< "\n";
}
}
generator()->log() << flush;
}
}
void PartnerFinder::setInitialQCDEvolutionScales(const ShowerParticleVector &particles,
const bool isDecayCase,
const bool setPartners) {
// Loop over particles and consider only coloured particles which don't
// have already their colour partner fixed and that don't have children
// (the latter requirement is relaxed in the case isDecayCase is true).
// Build a map which has as key one of these particles (i.e. a pointer
// to a ShowerParticle object) and as a corresponding value the vector
// of all its possible *normal* candidate colour partners, defined as follows:
// --- have colour, and no children (this is not required in the case
// isDecayCase is true);
// --- if both are initial (incoming) state particles, then the (non-null) colourLine()
// of one of them must match the (non-null) antiColourLine() of the other.
// --- if one is an initial (incoming) state particle and the other is
// a final (outgoing) state particle, then both must have the
// same (non-null) colourLine() or the same (non-null) antiColourLine();
// Notice that this definition exclude the special case of baryon-violating
// processes (as in R-parity Susy), which will show up as particles
// without candidate colour partners, and that we will be treated a part later
// (this means that no modifications of the following loop is needed!
for ( const auto & sp : particles ) {
// Skip colourless particles
if(!sp->data().coloured()) continue;
// find the partners
auto partners = findQCDPartners(sp,particles);
// must have a partner
if(partners.empty()) {
throw Exception() << "`Failed to make colour connections in "
<< "PartnerFinder::setQCDInitialEvolutionScales"
<< *sp
<< Exception::eventerror;
}
// Calculate the evolution scales for all possible pairs of of particles
vector<pair<Energy,Energy> > scales;
int position = -1;
for(size_t ix=0; ix< partners.size(); ++ix) {
scales.push_back(calculateInitialEvolutionScales(ShowerPPair(sp, partners[ix].second),isDecayCase));
if (!setPartners && partners[ix].second) position = ix;
}
assert(setPartners || position >= 0);
// set partners if required
if (setPartners) {
// In the case of more than one candidate colour partners,
// there are now two approaches to choosing the partner. The
// first method is based on two assumptions:
// 1) the choice of which is the colour partner is done
// *randomly* between the available candidates.
// 2) the choice of which is the colour partner is done
// *independently* from each particle: in other words,
// if for a particle "i" its selected colour partner is
// the particle "j", then the colour partner of "j"
// does not have to be necessarily "i".
// The second method always chooses the furthest partner
// for hard gluons and gluinos.
// random choice
if( partnerMethod_ == 0 ) {
// random choice of partner
position = UseRandom::irnd(partners.size());
}
// take the one with largest angle
else if (partnerMethod_ == 1 ) {
if (sp->perturbative() == 1 &&
sp->dataPtr()->iColour()==PDT::Colour8 ) {
assert(partners.size()==2);
// Determine largest angle
double maxAngle(0.);
for(unsigned int ix=0;ix<partners.size();++ix) {
double angle = sp->momentum().vect().
angle(partners[ix].second->momentum().vect());
if(angle>maxAngle) {
maxAngle = angle;
position = ix;
}
}
}
else position = UseRandom::irnd(partners.size());
}
else assert(false);
// set the evolution partner
sp->partner(partners[position].second);
}
// primary partner set, set the others and do the scale
for(size_t ix=0; ix<partners.size(); ++ix) {
sp->addPartner(ShowerParticle::EvolutionPartner(partners[ix].second,1.,partners[ix].first,
scales[ix].first));
}
// set scales for all interactions to that of the partner, default
Energy scale = scales[position].first;
for(unsigned int ix=0;ix<partners.size();++ix) {
if(partners[ix].first==ShowerPartnerType::QCDColourLine) {
sp->scales().QCD_c =
sp->scales().QCD_c_noAO =
(scaleChoice_==0 ? scale : scales[ix].first);
}
else if(partners[ix].first==ShowerPartnerType::QCDAntiColourLine) {
sp->scales().QCD_ac =
sp->scales().QCD_ac_noAO =
(scaleChoice_==0 ? scale : scales[ix].first);
}
else assert(false);
}
}
}
void PartnerFinder::setInitialQEDEvolutionScales(const ShowerParticleVector &particles,
const bool isDecayCase,
const bool setPartners) {
// loop over all the particles
for(const auto & sp : particles) {
// not charged or photon continue
if(!sp->dataPtr()->charged() && sp->dataPtr()->id()!=ParticleID::gamma) continue;
// find the potential partners
vector<pair<double,tShowerParticlePtr> > partners = findQEDPartners(sp,particles,isDecayCase);
if(partners.empty()) {
throw Exception() << "Failed to find partner in "
<< "PartnerFinder::setQEDInitialEvolutionScales"
<< *sp << Exception::eventerror;
}
// calculate the probabilities
double prob(0.);
for(unsigned int ix=0;ix<partners.size();++ix) prob += partners[ix].first;
// normalise
for(unsigned int ix=0;ix<partners.size();++ix) partners[ix].first /= prob;
// set the partner if required
int position(-1);
// use QCD partner if set
if(!setPartners&&sp->partner()) {
for(unsigned int ix=0;ix<partners.size();++ix) {
if(sp->partner()==partners[ix].second) {
position = ix;
break;
}
}
}
// set the partner
if(setPartners||!sp->partner()||position<0) {
prob = UseRandom::rnd();
for(unsigned int ix=0;ix<partners.size();++ix) {
if(partners[ix].first>prob) {
position = ix;
break;
}
prob -= partners[ix].first;
}
if(position>=0&&(setPartners||!sp->partner())) {
sp->partner(partners[position].second);
}
}
// must have a partner
if(position<0) throw Exception() << "Failed to find partner in "
<< "PartnerFinder::setQEDInitialEvolutionScales"
<< *sp << Exception::eventerror;
// Calculate the evolution scales for all possible pairs of of particles
vector<pair<Energy,Energy> > scales;
for(unsigned int ix=0;ix< partners.size();++ix) {
scales.push_back(calculateInitialEvolutionScales(ShowerPPair(sp,partners[ix].second),
isDecayCase));
}
// store all the possible partners
for(unsigned int ix=0;ix<partners.size();++ix) {
sp->addPartner(ShowerParticle::EvolutionPartner(partners[ix].second,
partners[ix].first,
ShowerPartnerType::QED,
scales[ix].first));
}
// set scales
sp->scales().QED = scales[position].first;
sp->scales().QED_noAO = scales[position].first;
}
}
pair<Energy,Energy> PartnerFinder::
calculateInitialEvolutionScales(const ShowerPPair &particlePair,
const bool isDecayCase, int key) {
bool FS1=FS(particlePair.first),FS2= FS(particlePair.second);
if(FS1 && FS2){
return calculateFinalFinalScales(particlePair.first->momentum(),particlePair.second->momentum(), key);
}
else if(FS1 && !FS2) {
pair<Energy,Energy> rval = calculateInitialFinalScales(particlePair.second->momentum(),
particlePair.first->momentum(),
isDecayCase);
return { rval.second, rval.first };
}
else if(!FS1 &&FS2)
return calculateInitialFinalScales(particlePair.first->momentum(),particlePair.second->momentum(),isDecayCase);
else
return calculateInitialInitialScales(particlePair.first->momentum(),particlePair.second->momentum());
}
vector< pair<ShowerPartnerType, tShowerParticlePtr> >
PartnerFinder::findQCDPartners(tShowerParticlePtr particle,
const ShowerParticleVector &particles) {
vector< pair<ShowerPartnerType, tShowerParticlePtr> > partners;
for(const auto & sp : particles) {
if(!sp->data().coloured() || particle==sp) continue;
// one initial-state and one final-state particle
if(FS(particle) != FS(sp)) {
// loop over all the colours of both particles
for(size_t ix=0; ix<CLSIZE(particle); ++ix) {
for(size_t jx=0; jx<CLSIZE(sp); ++jx) {
if((CL(particle,ix) && CL(particle,ix)==CL(sp,jx))) {
partners.push_back({ ShowerPartnerType:: QCDColourLine, sp });
}
}
}
//loop over all the anti-colours of both particles
for(size_t ix=0; ix<ACLSIZE(particle); ++ix) {
for(size_t jx=0; jx<ACLSIZE(sp); ++jx) {
if((ACL(particle,ix) && ACL(particle,ix)==ACL(sp,jx))) {
partners.push_back({ ShowerPartnerType::QCDAntiColourLine, sp });
}
}
}
}
// two initial-state or two final-state particles
else {
//loop over the colours of the first particle and the anti-colours of the other
for(size_t ix=0; ix<CLSIZE(particle); ++ix){
for(size_t jx=0; jx<ACLSIZE(sp); ++jx){
if(CL(particle,ix) && CL(particle,ix)==ACL(sp,jx)) {
partners.push_back({ ShowerPartnerType:: QCDColourLine, sp });
}
}
}
//loop over the anti-colours of the first particle and the colours of the other
for(size_t ix=0; ix<ACLSIZE(particle); ++ix){
for(size_t jx=0; jx<CLSIZE(sp); jx++){
if(ACL(particle,ix) && ACL(particle,ix)==CL(sp,jx)) {
partners.push_back({ ShowerPartnerType::QCDAntiColourLine, sp });
}
}
}
}
}
// if we haven't found any partners look for RPV
if (partners.empty()) {
// special for RPV
tColinePtr col = CL(particle);
if(FS(particle)&&col&&col->sourceNeighbours().first) {
tColinePair cpair = col->sourceNeighbours();
for(const auto & sp : particles) {
if(( FS(sp) && ( CL(sp) == cpair.first || CL(sp) == cpair.second))||
(!FS(sp) && (ACL(sp) == cpair.first || ACL(sp) == cpair.second ))) {
partners.push_back({ ShowerPartnerType:: QCDColourLine, sp });
}
}
}
else if(col&&col->sinkNeighbours().first) {
tColinePair cpair = col->sinkNeighbours();
for(const auto & sp : particles) {
if(( FS(sp) && (ACL(sp) == cpair.first || ACL(sp) == cpair.second))||
(!FS(sp) && ( CL(sp) == cpair.first || CL(sp) == cpair.second))) {
partners.push_back({ ShowerPartnerType:: QCDColourLine, sp });
}
}
}
col = ACL(particle);
if(FS(particle)&&col&&col->sinkNeighbours().first) {
tColinePair cpair = col->sinkNeighbours();
for(const auto & sp : particles) {
if(( FS(sp) && (ACL(sp) == cpair.first || ACL(sp) == cpair.second))||
(!FS(sp) && ( CL(sp) == cpair.first || CL(sp) == cpair.second ))) {
partners.push_back({ ShowerPartnerType::QCDAntiColourLine, sp });
}
}
}
else if(col&&col->sourceNeighbours().first) {
tColinePair cpair = col->sourceNeighbours();
for(const auto & sp : particles) {
if(( FS(sp) && ( CL(sp) == cpair.first || CL(sp) == cpair.second))||
(!FS(sp) && (ACL(sp) == cpair.first ||ACL(sp) == cpair.second))) {
partners.push_back({ ShowerPartnerType::QCDAntiColourLine, sp });
}
}
}
}
// return the partners
return partners;
}
vector< pair<double, tShowerParticlePtr> >
PartnerFinder::findQEDPartners(tShowerParticlePtr particle,
const ShowerParticleVector & particles,
const bool isDecayCase) {
vector< pair<double, tShowerParticlePtr> > partners;
const double pcharge =
particle->id()==ParticleID::gamma ? 1 : double(particle->data().iCharge());
vector< pair<double, tShowerParticlePtr> > photons;
for (const auto & sp : particles) {
if (particle == sp) continue;
if (sp->id()==ParticleID::gamma) photons.push_back(make_pair(1.,sp));
if (!sp->data().charged() ) continue;
double charge = pcharge*double((sp)->data().iCharge());
if ( FS(particle) != FS(sp) ) charge *=-1.;
if ( QEDPartner_ != 0 && !isDecayCase ) {
// only include II and FF as requested
if ( QEDPartner_ == 1 && FS(particle) != FS(sp) )
continue;
// only include IF is requested
else if (QEDPartner_ == 2 && FS(particle) == FS(sp) )
continue;
}
if (particle->id()==ParticleID::gamma) charge = -abs(charge);
// only keep positive dipoles
if (charge<0.) partners.push_back({ -charge, sp });
}
if (particle->id()==ParticleID::gamma && partners.empty())
return photons;
return partners;
}
void PartnerFinder::setInitialEWEvolutionScales(const ShowerParticleVector &particles,
const bool isDecayCase,
const bool setPartners) {
// loop over all the particles
for(ShowerParticleVector::const_iterator cit = particles.begin();
cit != particles.end(); ++cit) {
// if not weakly interacting continue
if( !weaklyInteracting( (**cit).dataPtr()))
continue;
// find the potential partners
vector<pair<double,tShowerParticlePtr> > partners = findEWPartners(*cit,particles,isDecayCase);
if(partners.empty()) {
throw Exception() << "Failed to find partner in "
<< "PartnerFinder::setEWInitialEvolutionScales"
<< (**cit) << Exception::eventerror;
}
// calculate the probabilities
double prob(0.);
for(unsigned int ix=0;ix<partners.size();++ix) prob += partners[ix].first;
// normalise
for(unsigned int ix=0;ix<partners.size();++ix) partners[ix].first /= prob;
// set the partner if required
int position(-1);
// use QCD partner if set
if(!setPartners&&(*cit)->partner()) {
for(unsigned int ix=0;ix<partners.size();++ix) {
if((*cit)->partner()==partners[ix].second) {
position = ix;
break;
}
}
}
// set the partner
if(setPartners||!(*cit)->partner()||position<0) {
prob = UseRandom::rnd();
for(unsigned int ix=0;ix<partners.size();++ix) {
if(partners[ix].first>prob) {
position = ix;
break;
}
prob -= partners[ix].first;
}
if(position>=0&&(setPartners||!(*cit)->partner())) {
(*cit)->partner(partners[position].second);
}
}
// must have a partner
if(position<0) throw Exception() << "Failed to find partner in "
<< "PartnerFinder::setEWInitialEvolutionScales"
<< (**cit) << Exception::eventerror;
// Calculate the evolution scales for all possible pairs of of particles
vector<pair<Energy,Energy> > scales;
for(unsigned int ix=0;ix< partners.size();++ix) {
scales.push_back(calculateInitialEvolutionScales(ShowerPPair(*cit,partners[ix].second),
isDecayCase, 0));
}
// store all the possible partners
for(unsigned int ix=0;ix<partners.size();++ix) {
(**cit).addPartner(ShowerParticle::EvolutionPartner(partners[ix].second,
partners[ix].first,
ShowerPartnerType::EW,
scales[ix].first));
}
// set scales
(**cit).scales().EW = scales[position].first;
}
}
vector< pair<double, tShowerParticlePtr> >
PartnerFinder::findEWPartners(tShowerParticlePtr particle,
const ShowerParticleVector &particles,
- const bool isDecayCase ) {
+ const bool ) {
vector< pair<double, tShowerParticlePtr> > partners;
for(ShowerParticlePtr partner : particles) {
if(particle==partner || !weaklyInteracting(partner->dataPtr()))
continue;
partners.push_back(make_pair(1.,partner));
}
return partners;
}
pair<Energy,Energy>
PartnerFinder::calculateFinalFinalScales(
const Lorentz5Momentum & p1,
const Lorentz5Momentum & p2, int key)
{
static const double eps=1e-7;
// Using JHEP 12(2003)045 we find that we need ktilde = 1/2(1+b-c+lambda)
// ktilde = qtilde^2/Q^2 therefore qtilde = sqrt(ktilde*Q^2)
// find momenta in rest frame of system
// calculate quantities for the scales
Energy2 Q2 = (p1+p2).m2();
double b = p1.mass2()/Q2;
double c = p2.mass2()/Q2;
if(b<0.) {
if(b<-eps) {
throw Exception() << "Negative Mass squared b = " << b
<< "in PartnerFinder::calculateFinalFinalScales()"
<< Exception::eventerror;
}
b = 0.;
}
if(c<0.) {
if(c<-eps) {
throw Exception() << "Negative Mass squared c = " << c
<< "in PartnerFinder::calculateFinalFinalScales()"
<< Exception::eventerror;
}
c = 0.;
}
// KMH & PR - 16 May 2008 - swapped lambda calculation from
// double lam=2.*p1.vect().mag()/Q; to sqrt(kallen(1,b,c)),
// which should be identical for p1 & p2 onshell in their COM
// but in the inverse construction for the Nason method, this
// was not the case, leading to misuse.
const double lam=sqrt((1.+sqrt(b)+sqrt(c))*(1.-sqrt(b)-sqrt(c))
*(sqrt(b)-1.-sqrt(c))*(sqrt(c)-1.-sqrt(b)));
Energy firstQ, secondQ;
double kappab(0.), kappac(0.);
//key = 0; // symmetric case pre-selection
switch(key) {
case 0: // symmetric case
firstQ = sqrt(0.5*Q2*(1.+b-c+lam));
secondQ = sqrt(0.5*Q2*(1.-b+c+lam));
break;
case 1: // maximum emission from both legs
kappab=4.*(1.-2.*sqrt(c)-b+c);
kappac=4.*(1.-2.*sqrt(b)-c+b);
firstQ = sqrt(Q2*kappab);
secondQ = sqrt(Q2*kappac);
break;
default:
assert(false);
}
// calculate the scales
return pair<Energy,Energy>(firstQ, secondQ);
}
pair<Energy,Energy>
PartnerFinder::calculateInitialFinalScales(const Lorentz5Momentum& pb, const Lorentz5Momentum& pc,
const bool isDecayCase) {
if(!isDecayCase) {
// In this case from JHEP 12(2003)045 we find the conditions
// ktilde_b = (1+c) and ktilde_c = (1+2c)
// We also find that c = m_c^2/Q^2. The process is a+b->c where
// particle a is not colour connected (considered as a colour singlet).
// Therefore we simply find that q_b = sqrt(Q^2+m_c^2) and
// q_c = sqrt(Q^2+2 m_c^2)
// We also assume that the first particle in the pair is the initial
// state particle and the second is the final state one c
const Energy2 mc2 = sqr(pc.mass());
const Energy2 Q2 = -(pb-pc).m2();
return { sqrt(Q2+mc2), sqrt(Q2+2*mc2) };
}
else {
// In this case from JHEP 12(2003)045 we find, for the decay
// process b->c+a(neutral), the condition
// (ktilde_b-1)*(ktilde_c-c)=(1/4)*sqr(1-a+c+lambda).
// We also assume that the first particle in the pair is the initial
// state particle (b) and the second is the final state one (c).
// - We find maximal phase space coverage through emissions from
// c if we set ktilde_c = 4.*(sqr(1.-sqrt(a))-c)
// - We find the most 'symmetric' way to populate the phase space
// occurs for (ktilde_b-1)=(ktilde_c-c)=(1/2)*(1-a+c+lambda)
// - We find the most 'smooth' way to populate the phase space
// occurs for...
Energy2 mb2(sqr(pb.mass()));
double a=(pb-pc).m2()/mb2;
double c=sqr(pc.mass())/mb2;
double lambda = 1. + a*a + c*c - 2.*a - 2.*c - 2.*a*c;
lambda = sqrt(max(lambda,0.));
const double PROD = 0.25*sqr(1. - a + c + lambda);
int key = 0;
double ktilde_b, ktilde_c, cosi = 0.;
switch (key) {
case 0: // the 'symmetric' choice
ktilde_c = 0.5*(1-a+c+lambda) + c ;
ktilde_b = 1.+PROD/(ktilde_c-c) ;
break;
case 1: // the 'maximal' choice
ktilde_c = 4.0*(sqr(1.-sqrt(a))-c);
ktilde_b = 1.+PROD/(ktilde_c-c) ;
break;
case 2: // the 'smooth' choice
c = max(c,1.*GeV2/mb2);
cosi = (sqr(1-sqrt(c))-a)/lambda;
ktilde_b = 2.0/(1.0-cosi);
ktilde_c = (1.0-a+c+lambda)*(1.0+c-a-lambda*cosi)/(2.0*(1.0+cosi));
break;
}
return { sqrt(mb2*ktilde_b), sqrt(mb2*ktilde_c) };
}
}
pair<Energy,Energy>
PartnerFinder::calculateInitialInitialScales(const Lorentz5Momentum& p1, const Lorentz5Momentum& p2) {
// This case is quite simple. From JHEP 12(2003)045 we find the condition
// that ktilde_b = ktilde_c = 1. In this case we have the process
// b+c->a so we need merely boost to the CM frame of the two incoming
// particles and then qtilde is equal to the energy in that frame
const Energy Q = sqrt((p1+p2).m2());
return {Q,Q};
}
diff --git a/Shower/QTilde/Kinematics/ShowerKinematics.cc b/Shower/QTilde/Kinematics/ShowerKinematics.cc
--- a/Shower/QTilde/Kinematics/ShowerKinematics.cc
+++ b/Shower/QTilde/Kinematics/ShowerKinematics.cc
@@ -1,71 +1,71 @@
// -*- C++ -*-
//
// ShowerKinematics.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 ShowerKinematics class.
//
#include "ShowerKinematics.h"
#include "ThePEG/Utilities/DescribeClass.h"
using namespace Herwig;
DescribeAbstractNoPIOClass<ShowerKinematics,Base>
describeShowerKinematics("Herwig::ShowerKinematics","Herwig.so");
void ShowerKinematics::updateChildren(const tShowerParticlePtr,
const ShowerParticleVector &,
- unsigned int pTscheme,
+ unsigned int ,
ShowerPartnerType) const {
throw Exception() << "Base class ShowerKinematics::updateChildren called,"
<< " should have been overriden in an inheriting class"
<< Exception::runerror;
}
void ShowerKinematics::resetChildren(const tShowerParticlePtr,
const ShowerParticleVector &) const {
throw Exception() << "Base class ShowerKinematics::resetChildren called,"
<< " should have been overriden in an inheriting class"
<< Exception::runerror;
}
void ShowerKinematics::updateParent(const tShowerParticlePtr,
const ShowerParticleVector &,
unsigned int ,
ShowerPartnerType) const {
throw Exception() << "Base class ShowerKinematics::updateParent called,"
<< " should have been overriden in an inheriting class"
<< Exception::runerror;
}
void ShowerKinematics::reconstructChildren(const tShowerParticlePtr,
const ShowerParticleVector &) const {
throw Exception() << "Base class ShowerKinematics::reconstructChildren called,"
<< " should have been overriden in an inheriting class"
<< Exception::runerror;
}
void ShowerKinematics::reconstructParent(const tShowerParticlePtr,
const ParticleVector &) const {
throw Exception() << "Base class ShowerKinematics::reconstructParent called,"
<< " should have been overriden in an inheriting class"
<< Exception::runerror;
}
void ShowerKinematics::reconstructLast(const tShowerParticlePtr,
Energy) const {
throw Exception() << "Base class ShowerKinematics::reconstructLast called,"
<< " should have been overriden in an inheriting class"
<< Exception::runerror;
}
void ShowerKinematics::updateLast(const tShowerParticlePtr,
Energy,Energy) const {
throw Exception() << "Base class ShowerKinematics::updatetLast called,"
<< " should have been overriden in an inheriting class"
<< Exception::runerror;
}
diff --git a/Shower/QTilde/Matching/PowhegShowerHandler.cc b/Shower/QTilde/Matching/PowhegShowerHandler.cc
--- a/Shower/QTilde/Matching/PowhegShowerHandler.cc
+++ b/Shower/QTilde/Matching/PowhegShowerHandler.cc
@@ -1,1104 +1,1103 @@
// -*- C++ -*-
//
// PowhegShowerHandler.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 PowhegShowerHandler class.
//
#include <config.h>
#include "PowhegShowerHandler.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Utilities/DescribeClass.h"
// include theses to have complete types
#include "Herwig/Shower/QTilde/Base/ShowerParticle.h"
#include "Herwig/PDF/MPIPDF.h"
#include "Herwig/PDF/MinBiasPDF.h"
#include "Herwig/Shower/QTilde/Base/ShowerTree.h"
#include "Herwig/Shower/QTilde/Kinematics/KinematicsReconstructor.h"
#include "Herwig/Shower/QTilde/Base/PartnerFinder.h"
#include "Herwig/PDF/HwRemDecayer.h"
#include "Herwig/Shower/QTilde/Base/ShowerProgenitor.h"
#include "Herwig/Shower/QTilde/Base/HardBranching.h"
#include "Herwig/Shower/QTilde/Base/HardTree.h"
#include "Herwig/MatrixElement/HwMEBase.h"
#include "ThePEG/MatrixElement/MEBase.h"
#include "ThePEG/MatrixElement/DiagramBase.fh"
#include "ThePEG/PDF/PartonExtractor.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
#include "Herwig/MatrixElement/Matchbox/Utility/DiagramDrawer.h"
using namespace Herwig;
namespace {
struct ParticleOrdering {
bool operator()(tcPDPtr p1, tcPDPtr p2) {
return abs(p1->id()) > abs(p2->id()) ||
( abs(p1->id()) == abs(p2->id()) && p1->id() > p2->id() ) ||
( p1->id() == p2->id() && p1->fullName() > p2->fullName() );
}
};
}
IBPtr PowhegShowerHandler::clone() const {
return new_ptr(*this);
}
IBPtr PowhegShowerHandler::fullclone() const {
return new_ptr(*this);
}
HardTreePtr PowhegShowerHandler::generateCKKW(ShowerTreePtr showerTree) const {
// hard subprocess
tSubProPtr sub = lastXCombPtr()->subProcess();
// real emission sub-process
tSubProPtr real = Factory()->hardTreeSubprocess();
// born emitter
emitter_ = Factory()->hardTreeEmitter();
spectator_ = Factory()->hardTreeSpectator();
// if no hard emission return
if ( !(real && emitter_>-1) )
return HardTreePtr();
// check emission
if(sub->outgoing().size()>=real->outgoing().size())
return HardTreePtr();
// check if decay has radiated don't add it
if(showerTree->outgoingLines().size() != sub->outgoing().size()) {
// loop over the decay trees
for(map<tShowerTreePtr,pair<tShowerProgenitorPtr,tShowerParticlePtr> >::const_iterator
tit=showerTree->treelinks().begin(); tit != showerTree->treelinks().end(); ++tit) {
if(tit->first->outgoingLines().empty()) continue;
// match the particles
set<tPPtr> decayProducts;
set<PPtr> outgoing(real->outgoing().begin(),real->outgoing().end());
for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator oit=tit->first->outgoingLines().begin();
oit!=tit->first->outgoingLines().end();++oit) {
tPPtr decayProd;
Energy2 dmin( 1e30*GeV2 );
tPPtr part = oit->second->original();
for( set<PPtr>::const_iterator it = outgoing.begin(); it != outgoing.end(); ++it ) {
if((**it).id()!=part->id()) continue;
Energy2 dtest =
sqr( part->momentum().x() - (**it).momentum().x() ) +
sqr( part->momentum().y() - (**it).momentum().y() ) +
sqr( part->momentum().z() - (**it).momentum().z() ) +
sqr( part->momentum().t() - (**it).momentum().t() );
dtest += 1e10*sqr(part->momentum().m()-(**it).momentum().m());
if( dtest < dmin ) {
decayProd = *it;
dmin = dtest;
}
}
if(!decayProd) {
throw Exception() << "PowhegShowerHandler::generateCKKW(). Can't match shower and hard trees."
<< Exception::eventerror;
}
outgoing .erase (decayProd);
decayProducts.insert(decayProd);
}
- bool coloured = false, foundParent = true;
+ bool foundParent = true;
tPPtr parent,emitted;
unsigned int nprod(0);
for( set<tPPtr>::const_iterator it = decayProducts.begin(); it != decayProducts.end(); ++it ) {
- coloured |= (**it).dataPtr()->coloured();
tPPtr newParent = !(**it).parents().empty() ? (**it).parents()[0] : tPPtr();
++nprod;
// check if from emission
if(newParent->id()==(**it).id()) {
if(newParent->children().size()!=2) foundParent=false;
bool foundChild(false), foundGluon(false);
for(unsigned int ix=0;ix<newParent->children().size();++ix) {
if(newParent->children()[ix]==*it) {
foundChild = true;
continue;
}
else if(newParent->children()[ix]->id()==ParticleID::g) {
foundGluon = true;
continue;
}
}
if(foundChild && foundGluon) {
newParent = !newParent->parents().empty() ? newParent->parents()[0] : tPPtr();
++nprod;
}
else
foundParent = false;
}
if(!newParent) {
foundParent = false;
}
else if(!parent) {
parent = newParent;
}
else {
if(parent!=newParent) foundParent = false;
}
}
if(nprod!=tit->first->outgoingLines().size()&&foundParent) {
if(decayRadiation_==0) {
throw Exception() << "The radiation generated in this event\n "
<< *real << "\n has been interepted as occuring in the "
<< "decay \nof a colour-singlet object and cannot be handled "
<< "you can either not simulated this process, "
<< "veto this class of events by using\n"
<< "set " << fullName() << ":DecayRadiation VetoEvent\n"
<< "or throw the hard radiation away using \n"
<< "set " << fullName() << ":DecayRadiation VetoRadiation\n"
<< "Please contact us at herwig@hepforge.org for advice\n"
<< "on how to simulate this process\n"
<< Exception::runerror;
}
else if(decayRadiation_==1) {
throw Exception() << "The radiation generated in this event\n "
<< *real << "\n has been interepted as occuring in the "
<< "decay \nof a colour-singlet object and cannot be handled "
<< "vetoing event\n"
<< Exception::eventerror;
}
else if(decayRadiation_==2) {
generator()->log() << "The radiation generated in this event\n "
<< *real << "\n has been interepted as occuring in the "
<< "decay \nof a colour-singlet object and cannot be handled "
<< "vetoing radiation\n";
return HardTreePtr();
}
else
assert(false);
}
}
}
tStdXCombPtr lastXC = dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr());
tStdXCombPtr headXC = lastXC->head();
if (headXC)
matrixElement_ = dynamic_ptr_cast<MEPtr>(headXC->matrixElement());
else if (lastXC)
matrixElement_ = dynamic_ptr_cast<MEPtr>(lastXC->matrixElement());
if (lastXC){
tStdXCombPtr projector= lastXC->lastProjector();
if (projector){
matrixElement_ = dynamic_ptr_cast<MEPtr>(projector->matrixElement());
setSubtractionIntegral(true);
}
else
setSubtractionIntegral(false);
}
assert(matrixElement_);
// create a hard tree by clustering the event
try {
hardTree(doClustering(real,showerTree));
} catch(exception &e) {
throw Exception() << "Caught a problem in PowhegShowerHandler::doClustering " << e.what()
<< Exception::eventerror;
}
// Get the HardTree from the CKKW handler.
CKKWTreePtr hardtree = hardTree().tree();
// zero to avoid MPI problems
Factory()->setHardTreeEmitter(-1);
Factory()->setHardTreeSubprocess(SubProPtr());
return hardtree;
}
PotentialTree PowhegShowerHandler::doClustering(tSubProPtr real,ShowerTreePtr showerTree) const {
// clear storage of the protoTrees
protoBranchings().clear();
protoTrees().clear();
hardTrees_.clear();
assert( matrixElement() );
// extract the XComb for the Born process
tStdXCombPtr lastXC;
if (subtractionIntegral()){
tStdXCombPtr lastXCReal = dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr());
lastXC = lastXCReal->lastProjector();
}
else
lastXC = dynamic_ptr_cast<tStdXCombPtr>(lastXCombPtr());
const StandardXComb xc= *lastXC;
// get the particles for the born process
PPair incomingBorn = xc.subProcess()->incoming();
ParticleVector outgoingBorn = xc.subProcess()->outgoing();
// get particles from the XComb object for the real process
ParticleVector outgoing = real->outgoing();
PPair incoming = real->incoming();
// loop through the FS particles and create ProtoBranchings
for( unsigned int i = 0; i < outgoing.size(); ++i) {
tPPtr parent = outgoing[i]->parents()[0];
ProtoBranchingPtr currentBranching =
new_ptr(ProtoBranching(outgoing[i]->dataPtr(),HardBranching::Outgoing,
outgoing[i]->momentum(),tSudakovPtr()));
currentBranching-> colourLine(outgoing[i]-> colourLine());
currentBranching->antiColourLine(outgoing[i]->antiColourLine());
protoBranchings().insert(currentBranching);
}
// add IS hardBranchings
ProtoBranchingPtr currentBranching =
new_ptr(ProtoBranching(incoming.first ->dataPtr(),HardBranching::Incoming,
incoming.first ->momentum(),tSudakovPtr()));
currentBranching-> colourLine(incoming.first-> colourLine());
currentBranching->antiColourLine(incoming.first->antiColourLine());
protoBranchings().insert(currentBranching);
currentBranching =
new_ptr(ProtoBranching(incoming.second->dataPtr(),HardBranching::Incoming,
incoming.second->momentum(),tSudakovPtr()));
currentBranching-> colourLine(incoming.second-> colourLine());
currentBranching->antiColourLine(incoming.second->antiColourLine());
protoBranchings().insert(currentBranching);
// create and initialise the first tree
ProtoTreePtr initialProtoTree = new_ptr( ProtoTree() );
for(set<ProtoBranchingPtr>::const_iterator it=protoBranchings().begin();
it!=protoBranchings().end();++it) {
initialProtoTree->addBranching(*it);
}
// fill _proto_trees with all possible trees
protoTrees().insert(initialProtoTree );
fillProtoTrees( initialProtoTree , xc.mePartonData()[emitter_]->id() );
// create a HardTree from each ProtoTree and fill hardTrees()
for( set< ProtoTreePtr >::const_iterator cit = protoTrees().begin();
cit != protoTrees().end(); ++cit ) {
set<tPPtr> bornParticles(outgoingBorn.begin(),outgoingBorn.end());
bornParticles.insert(incomingBorn.first );
bornParticles.insert(incomingBorn.second);
PotentialTree newTree;
newTree.tree((**cit).createHardTree());
// new check based on the colour structure
map<ColinePtr,ColinePtr> cmap;
// make the colour connections in the tree
ShowerParticleVector branchingParticles;
map<ShowerParticlePtr,HardBranchingPtr> branchingMap;
bool matched(true);
int iemitter(-1);
HardBranchingPtr emitter;
map<int,HardBranchingPtr> locMap;
for( set< HardBranchingPtr >::iterator it = newTree.tree()->branchings().begin();
it != newTree.tree()->branchings().end(); ++it ) {
matched = true;
// map the particle to the branching for future use
branchingParticles.push_back((**it).branchingParticle());
branchingMap.insert(make_pair((**it).branchingParticle(),*it));
tPPtr bornPartner;
if((**it).status()==HardBranching::Incoming) {
HardBranchingPtr parent=*it;
while(parent->parent()) {
parent = parent->parent();
};
if(parent->branchingParticle()->momentum().z()/incomingBorn.first->momentum().z()>0.) {
bornPartner = incomingBorn.first;
if(!parent->children().empty()) {
iemitter = 0;
emitter = *it;
}
locMap[0] = *it;
}
else {
bornPartner = incomingBorn.second;
if(!parent->children().empty()) {
iemitter = 1;
emitter = *it;
}
locMap[1] = *it;
}
}
else {
Energy2 dmin( 1e30*GeV2 );
for(set<tPPtr>::const_iterator bit=bornParticles.begin();bit!=bornParticles.end();
++bit) {
if((**it).branchingParticle()->id()!=(**bit).id()) continue;
if(*bit==incomingBorn.first||*bit==incomingBorn.second) continue;
Energy2 dtest =
sqr( (**bit).momentum().x() - (**it).branchingParticle()->momentum().x() ) +
sqr( (**bit).momentum().y() - (**it).branchingParticle()->momentum().y() ) +
sqr( (**bit).momentum().z() - (**it).branchingParticle()->momentum().z() ) +
sqr( (**bit).momentum().t() - (**it).branchingParticle()->momentum().t() );
dtest += 1e10*sqr((**bit).momentum().m()-(**it).branchingParticle()->momentum().m());
if( dtest < dmin ) {
bornPartner = *bit;
dmin = dtest;
}
}
// find the map
int iloc(-1);
for(unsigned int ix=0;ix<outgoingBorn.size();++ix) {
if(outgoingBorn[ix]==bornPartner) {
iloc = ix+2;
break;
}
}
if(!(**it).children().empty()) {
emitter = *it;
iemitter = iloc;
}
locMap[iloc]= *it;
}
if(!bornPartner) {
matched=false;
break;
}
bornParticles.erase(bornPartner);
// skip the next block if not enforcing colour consistency
if(!enforceColourConsistency_) continue;
if((**it).branchingParticle()->colourLine()) {
if(cmap.find((**it).branchingParticle()->colourLine())!=cmap.end()) {
if(cmap[(**it).branchingParticle()->colourLine()]!=bornPartner->colourLine()) {
matched=false;
}
}
else {
cmap[(**it).branchingParticle()->colourLine()] = bornPartner->colourLine();
}
}
if((**it).branchingParticle()->antiColourLine()) {
if(cmap.find((**it).branchingParticle()->antiColourLine())!=cmap.end()) {
if(cmap[(**it).branchingParticle()->antiColourLine()]!=bornPartner->antiColourLine()) {
matched=false;
}
}
else {
cmap[(**it).branchingParticle()->antiColourLine()] = bornPartner->antiColourLine();
}
}
// require a match
if(!matched) break;
}
// if no match continue
if(!matched) continue;
// now sort out any decays
if(showerTree->outgoingLines().size()+showerTree->incomingLines().size()
!= newTree.tree()->branchings().size()) {
if(showerTree->treelinks().empty()) {
matched = false;
continue;
}
// loop over the decay trees
for(map<tShowerTreePtr,pair<tShowerProgenitorPtr,tShowerParticlePtr> >::const_iterator
tit=showerTree->treelinks().begin(); tit != showerTree->treelinks().end(); ++tit) {
if(tit->first->outgoingLines().empty()) continue;
set<HardBranchingPtr> decayProducts;
set<HardBranchingPtr> branchings = newTree.tree()->branchings();
// match the particles
for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator oit=tit->first->outgoingLines().begin();
oit!=tit->first->outgoingLines().end();++oit) {
HardBranchingPtr decayProd;
Energy2 dmin( 1e30*GeV2 );
tPPtr part = oit->second->original();
for( set< HardBranchingPtr >::iterator it = branchings.begin(); it != branchings.end(); ++it ) {
if((**it).status()==HardBranching::Incoming ) continue;
if((**it).branchingParticle()->id()!=part->id()) continue;
Energy2 dtest =
sqr( part->momentum().x() - (**it).branchingParticle()->momentum().x() ) +
sqr( part->momentum().y() - (**it).branchingParticle()->momentum().y() ) +
sqr( part->momentum().z() - (**it).branchingParticle()->momentum().z() ) +
sqr( part->momentum().t() - (**it).branchingParticle()->momentum().t() );
dtest += 1e10*sqr(part->momentum().m()-(**it).branchingParticle()->momentum().m());
if( dtest < dmin ) {
decayProd = *it;
dmin = dtest;
}
}
if(!decayProd) {
throw Exception() << "PowhegShowerHandler::generateCKKW(). Can't match shower and hard trees."
<< Exception::eventerror;
}
branchings .erase (decayProd);
decayProducts.insert(decayProd);
}
// erase the decay products
Lorentz5Momentum pnew,pshower;
for(set<HardBranchingPtr>::iterator it = decayProducts.begin(); it!=decayProducts.end(); ++it) {
newTree.tree()->branchings().erase(*it);
pnew += (**it).branchingParticle()->momentum();
pshower += (**it).showerMomentum();
}
pnew .setMass(tit->second.second->mass());
pshower.setMass(tit->second.second->mass());
pnew .rescaleEnergy();
pshower.rescaleEnergy();
// create the decaying particle
ShowerParticlePtr particle = new_ptr( ShowerParticle( tit->second.second->dataPtr() , true ) );
particle->set5Momentum( pnew );
HardBranchingPtr newBranch = new_ptr( HardBranching( particle, tSudakovPtr(),
HardBranchingPtr(),
HardBranching::Outgoing ) );
newBranch->showerMomentum(pshower);
newTree.tree()->branchings().insert(newBranch);
}
}
// if no match continue
if(!matched) continue;
// find the colour partners
try {
partnerFinder()
->setInitialEvolutionScales(branchingParticles,false,
ShowerInteraction::QCD,true);
}
catch( Exception & e ) {
generator()->log() << "Problem in set evolution scales in "
<< "PowhegShowerHandler::doClustering(). Exception was"
<< e.what();
continue;
}
for(unsigned int ix=0;ix<branchingParticles.size();++ix) {
if(branchingParticles[ix]->partner()) {
HardBranchingPtr partner = branchingMap[branchingParticles[ix]->partner()];
branchingMap[branchingParticles[ix]]->colourPartner(partner);
}
}
if(forcePartners_) {
locMap[emitter_ ]->colourPartner(locMap[spectator_]);
locMap[spectator_]->colourPartner(locMap[emitter_ ]);
locMap[emitter_ ]->branchingParticle()->partner(locMap[spectator_]->branchingParticle());
locMap[spectator_]->branchingParticle()->partner(locMap[emitter_ ]->branchingParticle());
}
newTree.tree()->partnersSet(true);
// set the beam particles
PPair beams = lastXCombPtr()->lastParticles();
// remove children of beams
PVector beam_children = beams.first->children();
if( (**newTree.tree()->incoming().begin()).branchingParticle()->momentum().z() /
beams.first->momentum().z() < 0.)
swap( beams.first, beams.second );
set<HardBranchingPtr>::iterator it = newTree.tree()->incoming().begin();
HardBranchingPtr br = *it;
br->beam( beams.first );
while ( !br->children().empty() ) {
for(unsigned int ix = 0; ix < br->children().size(); ++ix ) {
if( br->children()[ix]->status() == HardBranching::Incoming ) {
br = br->children()[ix];
break;
}
}
br->beam( beams.first );
}
++it;
br = *it;
br->beam( beams.second );
while ( !br->children().empty() ) {
for( unsigned int ix = 0; ix < br->children().size(); ++ix ) {
if( br->children()[ix]->status() == HardBranching::Incoming ) {
br = br->children()[ix];
break;
}
}
br->beam( beams.second );
}
// check the emitter and the spectator some how
if(iemitter!=emitter_) continue;
//do inverse momentum reconstruction
if( !kinematicsReconstructor()
->deconstructHardJets( newTree.tree(), ShowerInteraction::QCD ) ) continue;
newTree.tree()->findNodes();
newTree.weight(1.);
hardTrees_.push_back( make_pair( newTree, 1. ) );
}
// select the tree
PotentialTree chosen_hardTree;
if (hardTrees_.size()==1) {
chosen_hardTree = hardTrees_[0].first;
}
else {
// if multiple trees pick the one with matching
// intermediate particle momenta
for (unsigned int il=0; il<hardTrees_.size(); ++il){
vector<pair <long int, Lorentz5Momentum> > particles;
PotentialTree testTree = hardTrees_[il].first;
CKKWTreePtr check = testTree.tree();
// get id and momenta of particles in hard tree
for (set< HardBranchingPtr >::iterator it=check->branchings().begin();
it!=check->branchings().end(); ++it) {
particles.push_back(make_pair((*it)->branchingParticle()->id(),
(*it)->branchingParticle()->momentum()));
if (!(*it)->children().empty()){
for (unsigned int ic=0; ic<(*it)->children().size(); ++ic)
particles.push_back(make_pair((*it)->children()[ic]->branchingParticle()->id(),
(*it)->children()[ic]->branchingParticle()->momentum()));
}
if ((*it)->parent()){
particles.push_back(make_pair((*it)->parent()->branchingParticle()->id(),
(*it)->parent()->branchingParticle()->momentum()));
if (!(*it)->parent()->children().empty()) {
for (unsigned int ic=0; ic<(*it)->parent()->children().size(); ++ic) {
if(*it==(*it)->parent()->children()[ic]) continue;
particles.push_back(make_pair((*it)->parent()->children()[ic]->branchingParticle()->id(),
(*it)->parent()->children()[ic]->branchingParticle()->momentum()));
}
}
}
}
// loop through and match to particles in real subprocess
vector<pair <long int, Lorentz5Momentum> >::iterator part = particles.begin();
// incoming
for (; part!=particles.end(); ++part){
if ((*part).first==real->incoming().first->id() &&
fuzzyEqual((*part).second, real->incoming().first->momentum()))
break;
}
if (part!=particles.end()) particles.erase(part);
part = particles.begin();
for (; part!=particles.end(); ++part){
if ((*part).first==real->incoming().second->id() &&
fuzzyEqual((*part).second, real->incoming().second->momentum()))
break;
}
if (part!=particles.end()) particles.erase(part);
// outgoing
for (unsigned int io=0; io<real->outgoing().size(); ++io){
part = particles.begin();
for (; part!=particles.end(); ++part){
if ((*part).first==real->outgoing()[io]->id() &&
fuzzyEqual((*part).second, real->outgoing()[io]->momentum()))
break;
}
if (part!=particles.end()) particles.erase(part);
}
// intermediate
for (unsigned int ii=0; ii<real->intermediates().size(); ++ii){
part = particles.begin();
for (; part!=particles.end(); ++part){
if ((*part).first==real->intermediates()[ii]->id() &&
fuzzyEqual((*part).second, real->intermediates()[ii]->momentum()))
break;
}
if (part!=particles.end()) particles.erase(part);
}
// intermediate CC with -1*momentum
for (unsigned int ii=0; ii<real->intermediates().size(); ++ii){
part = particles.begin();
for (; part!=particles.end(); ++part){
if (!real->intermediates()[ii]->coloured() ||
(real->intermediates()[ii]->hasColour() &&
real->intermediates()[ii]->hasAntiColour())){
if ((*part).first==real->intermediates()[ii]->id() &&
fuzzyEqual((*part).second, -1.*real->intermediates()[ii]->momentum()) )
break;
}
else {
if ((*part).first==-1.*real->intermediates()[ii]->id() &&
fuzzyEqual((*part).second, -1.*real->intermediates()[ii]->momentum()) )
break;
}
}
if (part!=particles.end()) particles.erase(part);
}
// if all particles match, set as hardtree
if (particles.empty()){
chosen_hardTree = testTree;
break;
}
}
}
protoBranchings().clear();
protoTrees().clear();
hardTrees_.clear();
if(! chosen_hardTree.tree() ) {
return PotentialTree();
}
else
return chosen_hardTree;
}
bool PowhegShowerHandler::checkDiagram(PotentialTree & tree,
tcDiagPtr loDiagram) const {
set<HardBranchingPtr>::const_iterator cit;
tcPDPair incoming;
multiset<tcPDPtr,ParticleOrdering> outgoing;
//get the incoming and outgoing partons involved in hard process
for( cit = tree.tree()->branchings().begin();
cit != tree.tree()->branchings().end(); ++cit ){
if( (*cit)->status() ==HardBranching::Incoming) {
HardBranchingPtr parent = *cit;
while(parent->parent()) parent = parent->parent();
if( parent->branchingParticle()->momentum().z()>ZERO )
incoming.first = (*cit)->branchingParticle()->dataPtr();
else
incoming.second = (*cit)->branchingParticle()->dataPtr();
}
else {
outgoing.insert( (*cit)->branchingParticle()->dataPtr() );
}
}
if(!incoming.first || !incoming.second)
return 0.;
pair<string,string> tag;
tag.first = incoming.first ->PDGName() + "," + incoming.second->PDGName() + "->";
tag.second = incoming.second ->PDGName() + "," + incoming.first ->PDGName() + "->";
string tag_out;
for ( multiset<tcPDPtr,ParticleOrdering>::iterator i = outgoing.begin();
i != outgoing.end(); ++i ) {
if ( i != outgoing.begin() ) tag_out += ",";
tag_out += (**i).PDGName();
}
tag.first += tag_out;
tag.second += tag_out;
// find the diagrams
if( tag.first == loDiagram->getTag() ||
tag.second == loDiagram->getTag() )
tree.diagram(loDiagram);
// check this is allowed
return tree.diagram();
}
void PowhegShowerHandler::fillProtoTrees( ProtoTreePtr currentProtoTree,long id ) const {
if(currentProtoTree->branchings().size()==(lastXCombPtr()->subProcess()->outgoing().size()+2))
return;
for( set<tProtoBranchingPtr>::const_iterator
ita = currentProtoTree->branchings().begin();
ita!=currentProtoTree->branchings().end();++ita) {
for( set<tProtoBranchingPtr>::const_iterator
itb = currentProtoTree->branchings().begin();
itb!=ita;++itb) {
// can't merge two incoming branchings
if( (**ita).status() == HardBranching::Incoming &&
(**itb).status() == HardBranching::Incoming ) continue;
// if branching must be outgoing, skip incoming
if(emitter_>=2 && ( (**ita).status() == HardBranching::Incoming ||
(**itb).status() == HardBranching::Incoming ))
continue;
// if branching must be incoming, skip outgoing
if(emitter_<2 && ( (**ita).status() != HardBranching::Incoming &&
(**itb).status() != HardBranching::Incoming ))
continue;
// get a new branching for this pair
ProtoBranchingPtr currentBranching = getCluster(*ita,*itb);
// check branching with the right PID
if( ! currentBranching ||
currentBranching->id() != id)
continue;
// branching allowed so make a new Tree out of these branchings
set< tProtoBranchingPtr > newTreeBranchings = currentProtoTree->branchings();
newTreeBranchings.erase(*ita);
newTreeBranchings.erase(*itb);
newTreeBranchings.insert(currentBranching);
ProtoTreePtr newProtoTree = new_ptr( ProtoTree( newTreeBranchings ) );
// remove duplicate trees
if( ! repeatProtoTree( newProtoTree ) ) protoTrees().insert( newProtoTree );
// remove the current tree if it hasn't already been removed
if( protoTrees().find( currentProtoTree ) != protoTrees().end() )
protoTrees().erase( currentProtoTree );
// do recursion
fillProtoTrees( newProtoTree , id);
}
}
}
bool PowhegShowerHandler::repeatProtoTree( ProtoTreePtr currentProtoTree ) const {
// loop over all prototrees and see
// how many ProtoBranchings of current ProtoTree are found in each
for( set< ProtoTreePtr >::const_iterator cit = protoTrees().begin();
cit != protoTrees().end(); ++cit ) {
unsigned int no_matches = 0;
for( set< tProtoBranchingPtr >::const_iterator ckt
= currentProtoTree->branchings().begin();
ckt != currentProtoTree->branchings().end(); ckt++ ) {
if( (*cit)->branchings().find( *ckt ) != (*cit)->branchings().end() )
++no_matches;
}
// return true if all match
if( no_matches == currentProtoTree->branchings().size() )
return true;
}
return false;
}
tProtoBranchingPtr PowhegShowerHandler::getCluster( tProtoBranchingPtr b1,
tProtoBranchingPtr b2 ) const {
// look for the clustered pair in protoBranchings_
for(set<ProtoBranchingPtr>::const_iterator cit = protoBranchings().begin();
cit != protoBranchings().end(); ++cit) {
// both outgoing
if(b1->status()==HardBranching::Outgoing &&
b2->status()==HardBranching::Outgoing) {
if((**cit).status()!=HardBranching::Outgoing||
(**cit).children().empty()) continue;
if( ( b1 == (**cit).children()[0] && b2 == (**cit).children()[1] ) ||
( b1 == (**cit).children()[1] && b2 == (**cit).children()[0] ) )
return *cit;
}
// first incoming
else if(b1->status()==HardBranching::Incoming) {
if((**cit).backChildren().empty() ) continue;
if(b1!=(**cit).backChildren()[0]) continue;
if(b2==(**cit).backChildren()[1]) return *cit;
}
// second incoming
else if(b2->status()==HardBranching::Incoming) {
if((**cit).backChildren().empty() ) continue;
if(b2!=(**cit).backChildren()[0]) continue;
if(b1==(**cit).backChildren()[1]) return *cit;
}
}
// is branching incoming or outgoing
bool incoming = b1->status()==HardBranching::Incoming ||
b2->status()==HardBranching::Incoming;
// get the branching
BranchingElement theBranching;
if( !incoming ) theBranching = allowedFinalStateBranching( b1, b2 );
else theBranching = allowedInitialStateBranching( b1, b2 );
//if branching is not allowed return null ProtoBrancing
if( !theBranching.sudakov ) return ProtoBranchingPtr();
// get the ParticleData object for the new branching
tcPDPtr particle_data = incoming ? theBranching.particles[1] : theBranching.particles[0];
// create clustered ProtoBranching
ProtoBranchingPtr clusteredBranch;
// outgoing
if( !incoming ) {
Lorentz5Momentum pairMomentum = b1->momentum() + b2->momentum();
pairMomentum.setMass(ZERO);
clusteredBranch = new_ptr(ProtoBranching(particle_data,HardBranching::Outgoing,
pairMomentum, theBranching.sudakov));
if(particle_data->iColour()==PDT::Colour0)
return ProtoBranchingPtr();
else if(particle_data->iColour()==PDT::Colour3) {
if(b1->particle()->iColour()==PDT::Colour3 && b2->particle()->iColour()==PDT::Colour8) {
if(b1->colourLine()!=b2->antiColourLine())
return ProtoBranchingPtr();
clusteredBranch->colourLine(b2->colourLine());
}
else if(b2->particle()->iColour()==PDT::Colour3 && b1->particle()->iColour()==PDT::Colour8) {
if(b2->colourLine()!=b1->antiColourLine())
return ProtoBranchingPtr();
clusteredBranch->antiColourLine(b1->colourLine());
}
else
assert(false);
clusteredBranch->type(ShowerPartnerType::QCDColourLine);
}
else if(particle_data->iColour()==PDT::Colour3bar) {
if(b1->particle()->iColour()==PDT::Colour3bar && b2->particle()->iColour()==PDT::Colour8) {
if(b1->antiColourLine()!=b2->colourLine())
return ProtoBranchingPtr();
clusteredBranch->antiColourLine(b2->antiColourLine());
}
else if(b2->particle()->iColour()==PDT::Colour3bar && b1->particle()->iColour()==PDT::Colour8) {
if(b2->antiColourLine()!=b1->colourLine())
return ProtoBranchingPtr();
clusteredBranch->antiColourLine(b1->antiColourLine());
}
else
assert(false);
clusteredBranch->type(ShowerPartnerType::QCDAntiColourLine);
}
else if(particle_data->iColour()==PDT::Colour8) {
tProtoBranchingPtr coloured,antiColoured;
if(b1->particle()->iColour()==PDT::Colour3 &&
b2->particle()->iColour()==PDT::Colour3bar) {
coloured = b1;
antiColoured = b2;
}
else if(b2->particle()->iColour()==PDT::Colour3 &&
b1->particle()->iColour()==PDT::Colour3bar) {
coloured = b2;
antiColoured = b1;
}
else if(b1->particle()->iColour()==PDT::Colour8 &&
b2->particle()->iColour()==PDT::Colour8 ) {
if(b1->colourLine()==b2->antiColourLine()) {
coloured = b2;
antiColoured = b1;
}
else if(b2->colourLine()==b1->antiColourLine()) {
coloured = b1;
antiColoured = b2;
}
else
return ProtoBranchingPtr();
}
else
assert(false);
// can't have colour self connected gluons
if(coloured-> colourLine()==antiColoured->antiColourLine())
return ProtoBranchingPtr();
clusteredBranch-> colourLine( coloured-> colourLine());
clusteredBranch->antiColourLine(antiColoured->antiColourLine());
// softest particle is the emitted
if(coloured->momentum().t()>antiColoured->momentum().t()) {
clusteredBranch->type(ShowerPartnerType::QCDAntiColourLine);
}
else {
clusteredBranch->type(ShowerPartnerType::QCDColourLine);
}
}
else
assert(false);
}
// incoming
else {
Lorentz5Momentum pairMomentum = b1->momentum() - b2->momentum();
pairMomentum.setMass( ZERO );
// check for CC
if( particle_data->CC() &&
( b1->id() != theBranching.particles[0]->id() ||
b2->id() != theBranching.particles[2]->id() ) ) {
particle_data = particle_data->CC();
}
clusteredBranch = new_ptr(ProtoBranching(particle_data,HardBranching::Incoming,
pairMomentum,theBranching.sudakov));
// work out the type of branching
if(b1->particle()->iColour()==PDT::Colour3) {
b1->type(ShowerPartnerType::QCDColourLine);
if(b2->particle()->iColour()==PDT::Colour3 &&
particle_data->iColour()==PDT::Colour8) {
if(b1->colourLine()==b2->colourLine())
return ProtoBranchingPtr();
clusteredBranch-> colourLine(b1->colourLine());
clusteredBranch->antiColourLine(b2->colourLine());
}
else if(b2->particle()->iColour()==PDT::Colour8 &&
particle_data->iColour()==PDT::Colour3) {
if(b1->colourLine()!=b2->colourLine())
return ProtoBranchingPtr();
clusteredBranch->colourLine(b2->antiColourLine());
}
else
assert(false);
}
else if(b1->particle()->iColour()==PDT::Colour3bar) {
b1->type(ShowerPartnerType::QCDAntiColourLine);
if(b2->particle()->iColour()==PDT::Colour3bar &&
particle_data->iColour()==PDT::Colour8) {
if(b1->antiColourLine()==b2->antiColourLine())
return ProtoBranchingPtr();
clusteredBranch-> colourLine(b2->antiColourLine());
clusteredBranch->antiColourLine(b1->antiColourLine());
}
else if(b2->particle()->iColour()==PDT::Colour8 &&
particle_data->iColour()==PDT::Colour3bar) {
if(b1->antiColourLine()!=b2->antiColourLine())
return ProtoBranchingPtr();
clusteredBranch->antiColourLine(b2->colourLine());
}
else
assert(false);
}
else if(b1->particle()->iColour()==PDT::Colour8) {
if(b2->particle()->iColour()==PDT::Colour3) {
if(b1->colourLine()!=b2->colourLine())
return ProtoBranchingPtr();
clusteredBranch->antiColourLine(b1->antiColourLine());
b1->type(ShowerPartnerType::QCDColourLine);
}
else if(b2->particle()->iColour()==PDT::Colour3bar) {
if(b1->antiColourLine()!=b2->antiColourLine())
return ProtoBranchingPtr();
clusteredBranch-> colourLine(b1->colourLine());
b1->type(ShowerPartnerType::QCDAntiColourLine);
}
else if(b2->particle()->iColour()==PDT::Colour8) {
if(b1->colourLine()==b2->colourLine()) {
b1->type(ShowerPartnerType::QCDColourLine);
clusteredBranch->antiColourLine(b1->antiColourLine());
clusteredBranch->colourLine(b2->antiColourLine());
}
else if(b1->antiColourLine()==b2->antiColourLine()) {
b1->type(ShowerPartnerType::QCDAntiColourLine);
clusteredBranch-> colourLine(b1->colourLine());
clusteredBranch->antiColourLine(b2->colourLine());
}
else {
return ProtoBranchingPtr();
}
}
else
assert(false);
}
else
assert(false);
}
protoBranchings().insert(clusteredBranch);
//set children relations
// outgoing
if( !incoming ){
clusteredBranch->addChild( b1 );
clusteredBranch->addChild( b2 );
}
else {
clusteredBranch->addBackChild( b1 );
clusteredBranch->addBackChild( b2 );
}
return clusteredBranch;
}
BranchingElement PowhegShowerHandler::
allowedFinalStateBranching( tProtoBranchingPtr & b1, tProtoBranchingPtr & b2) const {
// check with normal ID's
pair< long, long > ptest = make_pair( b1->id(), b2->id() );
map< pair< long, long >, BranchingElement >::const_iterator
split = allowedFinal_.find(ptest);
if( split != allowedFinal_.end() ) {
if( split->second.particles[1]->id() != ptest.first ) swap( b1, b2 );
return split->second;
}
// check with CC
if( b1->particle()->CC() ) ptest.first *= -1;
if( b2->particle()->CC() ) ptest.second *= -1;
split = allowedFinal_.find( ptest );
if( split != allowedFinal_.end() ) {
// cc the idlist only be for qbar g clusterings
BranchingElement ccBranch = split->second;
swap(ccBranch.particles,ccBranch.conjugateParticles);
if( split->second.particles[1]->id() != ptest.first ) swap( b1, b2);
return ccBranch;
}
// not found found null pointer
return BranchingElement();
}
BranchingElement PowhegShowerHandler::allowedInitialStateBranching( tProtoBranchingPtr & b1,
tProtoBranchingPtr & b2) const {
if(b2->status()==HardBranching::Incoming) swap(b1,b2);
// is initial parton an antiparticle
bool cc = b1->id() < 0;
//gives range of allowedInitial_ with matching first abs( id )
pair< multimap< long, BranchingElement >::const_iterator,
multimap< long, BranchingElement >::const_iterator >
location = allowedInitial_.equal_range( abs( b1->id() ) );
//iterates over this range
for( multimap< long, BranchingElement >::const_iterator it = location.first;
it != location.second; ++it ) {
//test id for second particle in pair
long idtest = cc ? it->second.conjugateParticles[2]->id() : it->second.particles[2]->id();
// does second id match the test
if( idtest == b2->id() ) return it->second;
//if the the IS parton is a gluon and charge conjugate of second parton mathes accept
if( idtest == -b2->id() &&
! b1->particle()->CC() ) return it->second;
}
// not found found null pointer
return BranchingElement();
}
bool PowhegShowerHandler::fuzzyEqual(Lorentz5Momentum a,
Lorentz5Momentum b) const{
// check momenta are within 1% of each other
if ( (a.e()==ZERO && b.e()==ZERO) || (a.e()/b.e()>0.99 && a.e()/b.e()<1.01) ){
if ((a.x()==ZERO && b.x()==ZERO) || (a.x()/b.x()>0.99 && a.x()/b.x()<1.01) ){
if ((a.y()==ZERO && b.y()==ZERO) || (a.y()/b.y()>0.99 && a.y()/b.y()<1.01) ){
if ((a.z()==ZERO && b.z()==ZERO) || (a.z()/b.z()>0.99 && a.z()/b.z()<1.01) )
return true;
}
}
}
return false;
}
void PowhegShowerHandler::doinit() {
QTildeShowerHandler::doinit();
// extract the allowed branchings
// final-state
for(BranchingList::const_iterator
it = splittingGenerator()->finalStateBranchings().begin();
it != splittingGenerator()->finalStateBranchings().end(); ++it) {
pair<long,long> prod(make_pair(it->second.particles[1]->id(),
it->second.particles[2]->id()));
allowedFinal_.insert(make_pair(prod,it->second));
swap(prod.first,prod.second);
allowedFinal_.insert(make_pair(prod,it->second));
}
// initial-state
for(BranchingList::const_iterator
it = splittingGenerator()->initialStateBranchings().begin();
it != splittingGenerator()->initialStateBranchings().end(); ++it) {
allowedInitial_.insert(make_pair(it->second.particles[0]->id(),it->second));
}
}
void PowhegShowerHandler::persistentOutput(PersistentOStream & os) const {
os << allowedInitial_ << allowedFinal_
<< subtractionIntegral_ << enforceColourConsistency_ << forcePartners_
<< decayRadiation_;
}
void PowhegShowerHandler::persistentInput(PersistentIStream & is, int) {
is >> allowedInitial_ >> allowedFinal_
>> subtractionIntegral_ >> enforceColourConsistency_ >> forcePartners_
>> decayRadiation_;
}
// Static variable needed for the type description system in ThePEG.
DescribeClass<PowhegShowerHandler,Herwig::QTildeShowerHandler>
describeHerwigPowhegShowerHandler("Herwig::PowhegShowerHandler",
"HwMatchbox.so HwMatching.so");
void PowhegShowerHandler::Init() {
static ClassDocumentation<PowhegShowerHandler> documentation
("The PowhegShowerHandler class");
static Switch<PowhegShowerHandler,bool> interfaceEnforceColourConsistency
("EnforceColourConsistency",
"Force the Born and real emission colour flows to be consistent",
&PowhegShowerHandler::enforceColourConsistency_, false, false, false);
static SwitchOption interfaceEnforceColourConsistencyYes
(interfaceEnforceColourConsistency,
"Yes",
"Enforce the consistency",
true);
static SwitchOption interfaceEnforceColourConsistencyNo
(interfaceEnforceColourConsistency,
"No",
"Don't enforce consistency",
false);
static Switch<PowhegShowerHandler,bool> interfaceForcePartners
("ForcePartners",
"Whether or not to force the partners to be those from the kinematic generation",
&PowhegShowerHandler::forcePartners_, false, false, false);
static SwitchOption interfaceForcePartnersYes
(interfaceForcePartners,
"Yes",
"Force them",
true);
static SwitchOption interfaceForcePartnersNo
(interfaceForcePartners,
"No",
"Don't force them",
false);
static Switch<PowhegShowerHandler,unsigned int> interfaceDecayRadiation
("DecayRadiation",
"Handling of radiation which is interpretted as having come from decays",
&PowhegShowerHandler::decayRadiation_, 0, false,false);
static SwitchOption interfaceDecayRadiationNotAllowed
(interfaceDecayRadiation,
"NotAllowed",
"Not allowed at all, run error will be thrown",
0);
static SwitchOption interfaceDecayRadiationVetoEvent
(interfaceDecayRadiation,
"VetoEvent",
"Veto the whole event",
1);
static SwitchOption interfaceDecayRadiationVetoRadiation
(interfaceDecayRadiation,
"VetoRadiation",
"Throw the radiation away but keep the event",
2);
}
diff --git a/Shower/QTilde/QTildeShowerHandler.cc b/Shower/QTilde/QTildeShowerHandler.cc
--- a/Shower/QTilde/QTildeShowerHandler.cc
+++ b/Shower/QTilde/QTildeShowerHandler.cc
@@ -1,3253 +1,3251 @@
// -*- C++ -*-
//
// QTildeShowerHandler.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 QTildeShowerHandler class.
//
#include "QTildeShowerHandler.h"
#include "ThePEG/Interface/Deleted.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Interface/Switch.h"
#include "ThePEG/Interface/Reference.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/EventRecord/Particle.h"
#include "ThePEG/Repository/UseRandom.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Utilities/EnumIO.h"
#include "Herwig/Shower/QTilde/Base/ShowerParticle.h"
#include "Herwig/PDF/MPIPDF.h"
#include "Herwig/PDF/MinBiasPDF.h"
#include "Herwig/Shower/QTilde/Base/ShowerTree.h"
#include "Herwig/Shower/QTilde/Base/HardTree.h"
#include "Herwig/Shower/QTilde/Kinematics/KinematicsReconstructor.h"
#include "Herwig/Shower/QTilde/Base/PartnerFinder.h"
#include "Herwig/PDF/HwRemDecayer.h"
#include "Herwig/Shower/QTilde/Base/ShowerVertex.h"
#include "ThePEG/Repository/CurrentGenerator.h"
#include "Herwig/MatrixElement/Matchbox/Base/SubtractedME.h"
#include "Herwig/MatrixElement/Matchbox/MatchboxFactory.h"
#include "ThePEG/PDF/PartonExtractor.h"
#include "Herwig/Shower/RealEmissionProcess.h"
#include "Herwig/Shower/QTilde/Kinematics/FS_QTildeShowerKinematics1to2.h"
#include "Herwig/Shower/QTilde/Kinematics/IS_QTildeShowerKinematics1to2.h"
#include "Herwig/Shower/QTilde/Kinematics/Decay_QTildeShowerKinematics1to2.h"
#include "Herwig/MatrixElement/MEMinBias.h"
using namespace Herwig;
bool QTildeShowerHandler::_hardEmissionWarn = true;
bool QTildeShowerHandler::_missingTruncWarn = true;
QTildeShowerHandler::QTildeShowerHandler() :
_maxtry(100), _meCorrMode(1), _evolutionScheme(1),
_hardVetoReadOption(false),
_iptrms(ZERO), _beta(0.), _gamma(ZERO), _iptmax(),
_limitEmissions(0), _initialenhance(1.), _finalenhance(1.),
_nReWeight(100), _reWeight(false),
interaction_(ShowerInteraction::ALL),
_trunc_Mode(true), _hardEmission(1),
_softOpt(2), _hardPOWHEG(false), muPt(ZERO)
{}
-QTildeShowerHandler::~QTildeShowerHandler() {}
-
IBPtr QTildeShowerHandler::clone() const {
return new_ptr(*this);
}
IBPtr QTildeShowerHandler::fullclone() const {
return new_ptr(*this);
}
void QTildeShowerHandler::persistentOutput(PersistentOStream & os) const {
os << _splittingGenerator << _maxtry
<< _meCorrMode << _hardVetoReadOption
<< _limitEmissions << _softOpt << _hardPOWHEG
<< ounit(_iptrms,GeV) << _beta << ounit(_gamma,GeV) << ounit(_iptmax,GeV)
<< _vetoes << _fullShowerVetoes << _nReWeight << _reWeight
<< _trunc_Mode << _hardEmission << _evolutionScheme
<< ounit(muPt,GeV) << oenum(interaction_)
<< _reconstructor << _partnerfinder;
}
void QTildeShowerHandler::persistentInput(PersistentIStream & is, int) {
is >> _splittingGenerator >> _maxtry
>> _meCorrMode >> _hardVetoReadOption
>> _limitEmissions >> _softOpt >> _hardPOWHEG
>> iunit(_iptrms,GeV) >> _beta >> iunit(_gamma,GeV) >> iunit(_iptmax,GeV)
>> _vetoes >> _fullShowerVetoes >> _nReWeight >> _reWeight
>> _trunc_Mode >> _hardEmission >> _evolutionScheme
>> iunit(muPt,GeV) >> ienum(interaction_)
>> _reconstructor >> _partnerfinder;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<QTildeShowerHandler,ShowerHandler>
describeHerwigQTildeShowerHandler("Herwig::QTildeShowerHandler", "HwShower.so");
void QTildeShowerHandler::Init() {
static ClassDocumentation<QTildeShowerHandler> documentation
("TheQTildeShowerHandler class is the main class"
" for the angular-ordered parton shower",
"The Shower evolution was performed using an algorithm described in "
"\\cite{Bahr:2008pv,Marchesini:1983bm,Marchesini:1987cf,Gieseke:2003rz,Masouminia:2021kne}.",
//
"%\\cite{Marchesini:1983bm}\n"
"\\bibitem{Marchesini:1983bm}\n"
" G.~Marchesini and B.~R.~Webber,\n"
" ``Simulation Of QCD Jets Including Soft Gluon Interference,''\n"
" Nucl.\\ Phys.\\ B {\\bf 238}, 1 (1984).\n"
" %%CITATION = NUPHA,B238,1;%%\n"
//
"%\\cite{Marchesini:1987cf}\n"
"\\bibitem{Marchesini:1987cf}\n"
" G.~Marchesini and B.~R.~Webber,\n"
" ``Monte Carlo Simulation of General Hard Processes with Coherent QCD\n"
" Radiation,''\n"
" Nucl.\\ Phys.\\ B {\\bf 310}, 461 (1988).\n"
" %%CITATION = NUPHA,B310,461;%%\n"
//
"%\\cite{Gieseke:2003rz}\n"
"\\bibitem{Gieseke:2003rz}\n"
" S.~Gieseke, P.~Stephens and B.~Webber,\n"
" ``New formalism for QCD parton showers,''\n"
" JHEP {\\bf 0312}, 045 (2003)\n"
" [arXiv:hep-ph/0310083].\n"
" %%CITATION = JHEPA,0312,045;%%\n"
//
"%\\cite{Masouminia:2021kne}\n"
"\\bibitem{Masouminia:2021kne}\n"
" M.~R.~Masouminia and P.~Richardson,\n"
" ``Implementation of angularly ordered electroweak parton shower in Herwig 7,''\n"
" JHEP {\\bf 04}, 112 (2022)\n"
" [arXiv:2108.10817 [hep-ph].\n"
" %%CITATION = JHEP,04,112;%%\n"
);
static Reference<QTildeShowerHandler,SplittingGenerator>
interfaceSplitGen("SplittingGenerator",
"A reference to the SplittingGenerator object",
&Herwig::QTildeShowerHandler::_splittingGenerator,
false, false, true, false);
static Parameter<QTildeShowerHandler,unsigned int> interfaceMaxTry
("MaxTry",
"The maximum number of attempts to generate the shower from a"
" particular ShowerTree",
&QTildeShowerHandler::_maxtry, 100, 1, 100000,
false, false, Interface::limited);
static Parameter<QTildeShowerHandler,unsigned int> interfaceNReWeight
("NReWeight",
"The number of attempts for the shower when reweighting",
&QTildeShowerHandler::_nReWeight, 100, 10, 10000,
false, false, Interface::limited);
static Switch<QTildeShowerHandler, unsigned int> ifaceMECorrMode
("MECorrMode",
"Choice of the ME Correction Mode",
&QTildeShowerHandler::_meCorrMode, 1, false, false);
static SwitchOption on
(ifaceMECorrMode,"HardPlusSoft","hard+soft on", 1);
static SwitchOption hard
(ifaceMECorrMode,"Hard","only hard on", 2);
static SwitchOption soft
(ifaceMECorrMode,"Soft","only soft on", 3);
static Switch<QTildeShowerHandler, bool> ifaceHardVetoReadOption
("HardVetoReadOption",
"Apply read-in scale veto to all collisions or just the primary one?",
&QTildeShowerHandler::_hardVetoReadOption, false, false, false);
static SwitchOption AllCollisions
(ifaceHardVetoReadOption,
"AllCollisions",
"Read-in pT veto applied to primary and secondary collisions.",
false);
static SwitchOption PrimaryCollision
(ifaceHardVetoReadOption,
"PrimaryCollision",
"Read-in pT veto applied to primary but not secondary collisions.",
true);
static Parameter<QTildeShowerHandler, Energy> ifaceiptrms
("IntrinsicPtGaussian",
"RMS of intrinsic pT of Gaussian distribution:\n"
"2*(1-Beta)*exp(-sqr(intrinsicpT/RMS))/sqr(RMS)",
&QTildeShowerHandler::_iptrms, GeV, ZERO, ZERO, 1000000.0*GeV,
false, false, Interface::limited);
static Parameter<QTildeShowerHandler, double> ifacebeta
("IntrinsicPtBeta",
"Proportion of inverse quadratic distribution in generating intrinsic pT.\n"
"(1-Beta) is the proportion of Gaussian distribution",
&QTildeShowerHandler::_beta, 0, 0, 1,
false, false, Interface::limited);
static Parameter<QTildeShowerHandler, Energy> ifacegamma
("IntrinsicPtGamma",
"Parameter for inverse quadratic:\n"
"2*Beta*Gamma/(sqr(Gamma)+sqr(intrinsicpT))",
&QTildeShowerHandler::_gamma,GeV, ZERO, ZERO, 100000.0*GeV,
false, false, Interface::limited);
static Parameter<QTildeShowerHandler, Energy> ifaceiptmax
("IntrinsicPtIptmax",
"Upper bound on intrinsic pT for inverse quadratic",
&QTildeShowerHandler::_iptmax,GeV, ZERO, ZERO, 100000.0*GeV,
false, false, Interface::limited);
static RefVector<QTildeShowerHandler,ShowerVeto> ifaceVetoes
("Vetoes",
"The vetoes to be checked during showering",
&QTildeShowerHandler::_vetoes, -1,
false,false,true,true,false);
static RefVector<QTildeShowerHandler,FullShowerVeto> interfaceFullShowerVetoes
("FullShowerVetoes",
"The vetos to be appliede on the full final state of the shower",
&QTildeShowerHandler::_fullShowerVetoes, -1, false, false, true, false, false);
static Switch<QTildeShowerHandler,unsigned int> interfaceLimitEmissions
("LimitEmissions",
"Limit the number and type of emissions for testing",
&QTildeShowerHandler::_limitEmissions, 0, false, false);
static SwitchOption interfaceLimitEmissionsNoLimit
(interfaceLimitEmissions,
"NoLimit",
"Allow an arbitrary number of emissions",
0);
static SwitchOption interfaceLimitEmissionsOneInitialStateEmission
(interfaceLimitEmissions,
"OneInitialStateEmission",
"Allow one emission in the initial state and none in the final state",
1);
static SwitchOption interfaceLimitEmissionsOneFinalStateEmission
(interfaceLimitEmissions,
"OneFinalStateEmission",
"Allow one emission in the final state and none in the initial state",
2);
static SwitchOption interfaceLimitEmissionsHardOnly
(interfaceLimitEmissions,
"HardOnly",
"Only allow radiation from the hard ME correction",
3);
static SwitchOption interfaceLimitEmissionsOneEmission
(interfaceLimitEmissions,
"OneEmission",
"Allow one emission in either the final state or initial state, but not both",
4);
static Switch<QTildeShowerHandler,bool> interfaceTruncMode
("TruncatedShower", "Include the truncated shower?",
&QTildeShowerHandler::_trunc_Mode, 1, false, false);
static SwitchOption interfaceTruncMode0
(interfaceTruncMode,"No","Truncated Shower is OFF", 0);
static SwitchOption interfaceTruncMode1
(interfaceTruncMode,"Yes","Truncated Shower is ON", 1);
static Switch<QTildeShowerHandler,int> interfaceHardEmission
("HardEmission",
"Whether to use ME corrections or POWHEG for the hardest emission",
&QTildeShowerHandler::_hardEmission, 0, false, false);
static SwitchOption interfaceHardEmissionNone
(interfaceHardEmission,
"None",
"No Corrections",
0);
static SwitchOption interfaceHardEmissionMECorrection
(interfaceHardEmission,
"MECorrection",
"Old fashioned ME correction",
1);
static SwitchOption interfaceHardEmissionPOWHEG
(interfaceHardEmission,
"POWHEG",
"Powheg style hard emission",
2);
static Switch<QTildeShowerHandler,ShowerInteraction> interfaceInteractions
("Interactions",
"The interactions to be used in the shower",
&QTildeShowerHandler::interaction_, ShowerInteraction::ALL, false, false);
static SwitchOption interfaceInteractionsQCD
(interfaceInteractions,
"QCD",
"Only QCD radiation",
ShowerInteraction::QCD);
static SwitchOption interfaceInteractionsQED
(interfaceInteractions,
"QED",
"Only QEd radiation",
ShowerInteraction::QED);
static SwitchOption interfaceInteractionEWOnly
(interfaceInteractions,
"EWOnly",
"Only EW",
ShowerInteraction::EW);
static SwitchOption interfaceInteractionQEDQCD
(interfaceInteractions,
"QEDQCD",
"QED and QCD",
ShowerInteraction::QEDQCD);
static SwitchOption interfaceInteractionALL
(interfaceInteractions,
"ALL",
"QED, QCD and EW",
ShowerInteraction::ALL);
static Deleted<QTildeShowerHandler> delReconstructionOption
("ReconstructionOption", "The old reconstruction option switch has been replaced with"
" the new EvolutionScheme switch, see arXiv:1904.11866 for details");
static Switch<QTildeShowerHandler,unsigned int> interfaceEvolutionScheme
("EvolutionScheme",
"The scheme to interpret the evolution variable in the case of multple emission.",
&QTildeShowerHandler::_evolutionScheme, 1, false, false);
static SwitchOption interfaceEvolutionSchemepT
(interfaceEvolutionScheme,
"pT",
"pT scheme",
0);
static SwitchOption interfaceEvolutionSchemeDotProduct
(interfaceEvolutionScheme,
"DotProduct",
"Dot-product scheme",
1);
static SwitchOption interfaceEvolutionSchemeQ2
(interfaceEvolutionScheme,
"Q2",
"Q2 scheme",
2);
static Switch<QTildeShowerHandler,unsigned int> interfaceSoftCorrelations
("SoftCorrelations",
"Option for the treatment of soft correlations in the parton shower",
&QTildeShowerHandler::_softOpt, 2, false, false);
static SwitchOption interfaceSoftCorrelationsNone
(interfaceSoftCorrelations,
"No",
"No soft correlations",
0);
static SwitchOption interfaceSoftCorrelationsFull
(interfaceSoftCorrelations,
"Full",
"Use the full eikonal",
1);
static SwitchOption interfaceSoftCorrelationsSingular
(interfaceSoftCorrelations,
"Singular",
"Use original Webber-Marchisini form",
2);
static Switch<QTildeShowerHandler,bool> interfaceHardPOWHEG
("HardPOWHEG",
"Treatment of powheg emissions which are too hard to have a shower interpretation",
&QTildeShowerHandler::_hardPOWHEG, false, false, false);
static SwitchOption interfaceHardPOWHEGAsShower
(interfaceHardPOWHEG,
"AsShower",
"Still interpret as shower emissions",
false);
static SwitchOption interfaceHardPOWHEGRealEmission
(interfaceHardPOWHEG,
"RealEmission",
"Generate shower from the real emmission configuration",
true);
static Reference<QTildeShowerHandler,KinematicsReconstructor> interfaceKinematicsReconstructor
("KinematicsReconstructor",
"Reference to the KinematicsReconstructor object",
&QTildeShowerHandler::_reconstructor, false, false, true, false, false);
static Reference<QTildeShowerHandler,PartnerFinder> interfacePartnerFinder
("PartnerFinder",
"Reference to the PartnerFinder object",
&QTildeShowerHandler::_partnerfinder, false, false, true, false, false);
}
tPPair QTildeShowerHandler::cascade(tSubProPtr sub,
XCPtr xcomb) {
// use me for reference in tex file etc
useMe();
prepareCascade(sub);
// set things up in the base class
resetWeights();
hard_=ShowerTreePtr();
decay_.clear();
done_.clear();
// start of the try block for the whole showering process
unsigned int countFailures=0;
while (countFailures<maxtry()) {
try {
decay_.clear();
done_.clear();
PerturbativeProcessPtr hard;
DecayProcessMap decay;
splitHardProcess(firstInteraction() ? tagged() :
tPVector(currentSubProcess()->outgoing().begin(),
currentSubProcess()->outgoing().end()),
hard,decay);
ShowerTree::constructTrees(hard_,decay_,hard,decay);
// if no hard process
if(!hard_) throw Exception() << "Shower starting with a decay"
<< "is not implemented"
<< Exception::runerror;
// perform the shower for the hard process
showerHardProcess(hard_,xcomb);
done_.push_back(hard_);
hard_->updateAfterShower(decay_);
// if no decaying particles to shower break out of the loop
if(decay_.empty()) break;
// shower the decay products
while(!decay_.empty()) {
// find particle whose production process has been showered
ShowerDecayMap::iterator dit = decay_.begin();
while(!dit->second->parent()->hasShowered() && dit!=decay_.end()) ++dit;
assert(dit!=decay_.end());
// get the particle
ShowerTreePtr decayingTree = dit->second;
// remove it from the multimap
decay_.erase(dit);
// make sure the particle has been decayed
QTildeShowerHandler::decay(decayingTree,decay_);
// now shower the decay
showerDecay(decayingTree);
done_.push_back(decayingTree);
decayingTree->updateAfterShower(decay_);
}
// suceeded break out of the loop
break;
}
catch (KinematicsReconstructionVeto) {
resetWeights();
++countFailures;
}
catch ( ... ) {
hard_=ShowerTreePtr();
decay_.clear();
done_.clear();
throw;
}
}
// if loop exited because of too many tries, throw event away
if (countFailures >= maxtry()) {
resetWeights();
hard_=ShowerTreePtr();
decay_.clear();
done_.clear();
throw Exception() << "Too many tries for main while loop "
<< "in QTildeShowerHandler::cascade()."
<< Exception::eventerror;
}
//enter the particles in the event record
fillEventRecord();
// clear storage
hard_=ShowerTreePtr();
decay_.clear();
done_.clear();
// non hadronic case return
if (!isResolvedHadron(incomingBeams().first ) &&
!isResolvedHadron(incomingBeams().second) )
return incomingBeams();
// remake the remnants (needs to be after the colours are sorted
// out in the insertion into the event record)
if ( firstInteraction() ) return remakeRemnant(sub->incoming());
//Return the new pair of incoming partons. remakeRemnant is not
//necessary here, because the secondary interactions are not yet
//connected to the remnants.
return make_pair(findFirstParton(sub->incoming().first ),
findFirstParton(sub->incoming().second));
}
void QTildeShowerHandler::fillEventRecord() {
// create a new step
StepPtr pstep = newStep();
assert(!done_.empty());
assert(done_[0]->isHard());
// insert the steps
for(unsigned int ix=0;ix<done_.size();++ix) {
done_[ix]->fillEventRecord(pstep,doISR(),doFSR());
}
}
HardTreePtr QTildeShowerHandler::generateCKKW(ShowerTreePtr ) const {
return HardTreePtr();
}
void QTildeShowerHandler::doinit() {
ShowerHandler::doinit();
// check on the reweighting
for(unsigned int ix=0;ix<_fullShowerVetoes.size();++ix) {
if(_fullShowerVetoes[ix]->behaviour()==1) {
_reWeight = true;
break;
}
}
if(_reWeight && maximumTries()<_nReWeight) {
throw Exception() << "Reweight being performed in the shower but the number of attempts for the"
<< "shower is less than that for the reweighting.\n"
<< "Maximum number of attempt for the shower "
<< fullName() << ":MaxTry is " << maximumTries() << "\nand for reweighting is "
<< fullName() << ":NReWeight is " << _nReWeight << "\n"
<< "we recommend the number of attempts is 10 times the number for reweighting\n"
<< Exception::runerror;
}
ShowerTree::_vmin2 = vMin();
ShowerTree::_spaceTime = includeSpaceTime();
}
void QTildeShowerHandler::doinitrun() {
ShowerHandler::doinitrun();
ShowerTree::_vmin2 = vMin();
ShowerTree::_spaceTime = includeSpaceTime();
}
void QTildeShowerHandler::generateIntrinsicpT(vector<ShowerProgenitorPtr> particlesToShower) {
if ( !ipTon() || !doISR() ) return;
// don't do anything for the moment for secondary scatters
if( !firstInteraction() ) return;
// generate intrinsic pT
for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
// only consider initial-state particles
if(particlesToShower[ix]->progenitor()->isFinalState()) continue;
if(!particlesToShower[ix]->progenitor()->dataPtr()->coloured()) continue;
Energy ipt;
if(UseRandom::rnd() > _beta) {
ipt=_iptrms*sqrt(-log(UseRandom::rnd()));
}
else {
ipt=_gamma*sqrt(pow(1.+sqr(_iptmax/_gamma), UseRandom::rnd())-1.);
}
pair<Energy,double> pt = make_pair(ipt,UseRandom::rnd(Constants::twopi));
_intrinsic[particlesToShower[ix]] = pt;
}
}
void QTildeShowerHandler::setupMaximumScales(const vector<ShowerProgenitorPtr> & p,
XCPtr xcomb) {
// let POWHEG events radiate freely
if(_hardEmission==2&&hardTree()) {
vector<ShowerProgenitorPtr>::const_iterator ckt = p.begin();
for (; ckt != p.end(); ckt++) (*ckt)->maxHardPt(Constants::MaxEnergy);
return;
}
// return if no vetos
if (!restrictPhasespace()) return;
// find out if hard partonic subprocess.
bool isPartonic(false);
map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator
cit = _currenttree->incomingLines().begin();
Lorentz5Momentum pcm;
for(; cit!=currentTree()->incomingLines().end(); ++cit) {
pcm += cit->first->progenitor()->momentum();
isPartonic |= cit->first->progenitor()->coloured();
}
// find minimum pt from hard process, the maximum pt from all outgoing
// coloured lines (this is simpler and more general than
// 2stu/(s^2+t^2+u^2)). Maximum scale for scattering processes will
// be transverse mass.
Energy ptmax = generator()->maximumCMEnergy();
// general case calculate the scale
if ( !hardScaleIsMuF() || (hardVetoReadOption()&&!firstInteraction()) ) {
// scattering process
if(currentTree()->isHard()) {
assert(xcomb);
// coloured incoming particles
if (isPartonic) {
map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
cjt = currentTree()->outgoingLines().begin();
for(; cjt!=currentTree()->outgoingLines().end(); ++cjt) {
if (cjt->first->progenitor()->coloured())
ptmax = min(ptmax,cjt->first->progenitor()->momentum().mt());
}
}
if (ptmax == generator()->maximumCMEnergy() ) ptmax = pcm.m();
if(hardScaleIsMuF()&&hardVetoReadOption()&&
!firstInteraction()) {
ptmax=min(ptmax,sqrt(xcomb->lastShowerScale()));
}
}
// decay, incoming() is the decaying particle.
else {
ptmax = currentTree()->incomingLines().begin()->first
->progenitor()->momentum().mass();
}
}
// hepeup.SCALUP is written into the lastXComb by the
// LesHouchesReader itself - use this by user's choice.
// Can be more general than this.
else {
if(currentTree()->isHard()) {
assert(xcomb);
ptmax = sqrt( xcomb->lastShowerScale() );
}
else {
ptmax = currentTree()->incomingLines().begin()->first
->progenitor()->momentum().mass();
}
}
ptmax *= hardScaleFactor();
// set maxHardPt for all progenitors. For partonic processes this
// is now the max pt in the FS, for non-partonic processes or
// processes with no coloured FS the invariant mass of the IS
vector<ShowerProgenitorPtr>::const_iterator ckt = p.begin();
for (; ckt != p.end(); ckt++) (*ckt)->maxHardPt(ptmax);
}
void QTildeShowerHandler::setupHardScales(const vector<ShowerProgenitorPtr> & p,
XCPtr xcomb) {
if ( hardScaleIsMuF() &&
(!hardVetoReadOption() || firstInteraction()) ) {
Energy hardScale = ZERO;
if(currentTree()->isHard()) {
assert(xcomb);
hardScale = sqrt( xcomb->lastShowerScale() );
}
else {
hardScale = currentTree()->incomingLines().begin()->first
->progenitor()->momentum().mass();
}
hardScale *= hardScaleFactor();
vector<ShowerProgenitorPtr>::const_iterator ckt = p.begin();
for (; ckt != p.end(); ckt++) (*ckt)->hardScale(hardScale);
muPt = hardScale;
}
}
void QTildeShowerHandler::showerHardProcess(ShowerTreePtr hard, XCPtr xcomb) {
_hardme = HwMEBasePtr();
// extract the matrix element
tStdXCombPtr lastXC = dynamic_ptr_cast<tStdXCombPtr>(xcomb);
if(lastXC) {
_hardme = dynamic_ptr_cast<HwMEBasePtr>(lastXC->matrixElement());
}
_decayme = HwDecayerBasePtr();
// set the current tree
currentTree(hard);
hardTree(HardTreePtr());
// work out the type of event
currentTree()->xcombPtr(dynamic_ptr_cast<StdXCombPtr>(xcomb));
currentTree()->identifyEventType();
checkFlags();
// generate the showering
doShowering(true,xcomb);
}
RealEmissionProcessPtr QTildeShowerHandler::hardMatrixElementCorrection(bool hard) {
// set the initial enhancement factors for the soft correction
_initialenhance = 1.;
_finalenhance = 1.;
// see if we can get the correction from the matrix element
// or decayer
RealEmissionProcessPtr real;
if(hard) {
if(_hardme&&_hardme->hasMECorrection()) {
_hardme->initializeMECorrection(_currenttree->perturbativeProcess(),
_initialenhance,_finalenhance);
if(hardMEC())
real =
_hardme->applyHardMatrixElementCorrection(_currenttree->perturbativeProcess());
}
}
else {
if(_decayme&&_decayme->hasMECorrection()) {
_decayme->initializeMECorrection(_currenttree->perturbativeProcess(),
_initialenhance,_finalenhance);
if(hardMEC())
real = _decayme->applyHardMatrixElementCorrection(_currenttree->perturbativeProcess());
}
}
return real;
}
ShowerParticleVector QTildeShowerHandler::createTimeLikeChildren(tShowerParticlePtr, IdList ids) {
// Create the ShowerParticle objects for the two children of
// the emitting particle; set the parent/child relationship
// if same as definition create particles, otherwise create cc
ShowerParticleVector children;
for(unsigned int ix=0;ix<2;++ix) {
children.push_back(new_ptr(ShowerParticle(ids[ix+1],true)));
if(children[ix]->id()==_progenitor->id()&&!ids[ix+1]->stable()&&abs(ids[ix+1]->id())!=ParticleID::tauminus)
children[ix]->set5Momentum(Lorentz5Momentum(_progenitor->progenitor()->mass()));
else
children[ix]->set5Momentum(Lorentz5Momentum(ids[ix+1]->mass()));
}
return children;
}
bool QTildeShowerHandler::timeLikeShower(tShowerParticlePtr particle,
ShowerInteraction type,
Branching fb, bool first) {
// don't do anything if not needed
if(_limitEmissions == 1 || hardOnly() ||
( _limitEmissions == 2 && _nfs != 0) ||
( _limitEmissions == 4 && _nfs + _nis != 0) ) {
if(particle->spinInfo()) particle->spinInfo()->develop();
return false;
}
// generate the emission
ShowerParticleVector children;
// generate the emission
if(!fb.kinematics)
fb = selectTimeLikeBranching(particle,type,HardBranchingPtr());
// no emission, return
if(!fb.kinematics) {
if(particle->spinInfo()) particle->spinInfo()->develop();
return false;
}
Branching fc[2] = {Branching(),Branching()};
assert(fb.kinematics);
// has emitted
// Assign the shower kinematics to the emitting particle.
particle->showerKinematics(fb.kinematics);
// check highest pT
if(fb.kinematics->pT()>progenitor()->highestpT())
progenitor()->highestpT(fb.kinematics->pT());
// create the children
children = createTimeLikeChildren(particle,fb.ids);
// update the children
particle->showerKinematics()->
updateChildren(particle, children,_evolutionScheme,fb.type);
// update number of emissions
++_nfs;
if(_limitEmissions!=0) {
if(children[0]->spinInfo()) children[0]->spinInfo()->develop();
if(children[1]->spinInfo()) children[1]->spinInfo()->develop();
if(particle->spinInfo()) particle->spinInfo()->develop();
return true;
}
// select branchings for children
fc[0] = selectTimeLikeBranching(children[0],type,HardBranchingPtr());
fc[1] = selectTimeLikeBranching(children[1],type,HardBranchingPtr());
// shower the first particle
if(fc[0].kinematics) timeLikeShower(children[0],type,fc[0],false);
if(children[0]->spinInfo()) children[0]->spinInfo()->develop();
// shower the second particle
if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],false);
if(children[1]->spinInfo()) children[1]->spinInfo()->develop();
particle->showerKinematics()->updateParent(particle, children,_evolutionScheme,fb.type);
// branching has happened
if(first&&!children.empty())
particle->showerKinematics()->resetChildren(particle,children);
if(particle->spinInfo()) particle->spinInfo()->develop();
return true;
}
bool
QTildeShowerHandler::spaceLikeShower(tShowerParticlePtr particle, PPtr beam,
ShowerInteraction type) {
//using the pdf's associated with the ShowerHandler assures, that
//modified pdf's are used for the secondary interactions via
//CascadeHandler::resetPDFs(...)
tcPDFPtr pdf;
if(beam == incomingBeams().first)
pdf = firstPDF().pdf();
if(beam == incomingBeams().second)
pdf = secondPDF().pdf();
Energy freeze = pdfFreezingScale();
// don't do anything if not needed
if(_limitEmissions == 2 || hardOnly() ||
( _limitEmissions == 1 && _nis != 0 ) ||
( _limitEmissions == 4 && _nis + _nfs != 0 ) ) {
if(particle->spinInfo()) particle->spinInfo()->develop();
return false;
}
Branching bb;
// generate branching
while (true) {
bb=_splittingGenerator->chooseBackwardBranching(*particle,beam,
_initialenhance,
_beam,type,
pdf,freeze);
// return if no emission
if(!bb.kinematics) {
if(particle->spinInfo()) particle->spinInfo()->develop();
return false;
}
// if not vetoed break
if(!spaceLikeVetoed(bb,particle)) break;
// otherwise reset scale and continue
particle->vetoEmission(bb.type,bb.kinematics->scale());
if(particle->spinInfo()) particle->spinInfo()->decayVertex(VertexPtr());
}
// assign the splitting function and shower kinematics
particle->showerKinematics(bb.kinematics);
if(bb.kinematics->pT()>progenitor()->highestpT())
progenitor()->highestpT(bb.kinematics->pT());
// For the time being we are considering only 1->2 branching
// particles as in Sudakov form factor
tcPDPtr part[2]={bb.ids[0],bb.ids[2]};
// Now create the actual particles, make the otherChild a final state
// particle, while the newParent is not
ShowerParticlePtr newParent = new_ptr(ShowerParticle(part[0],false));
ShowerParticlePtr otherChild = new_ptr(ShowerParticle(part[1],true,true));
ShowerParticleVector theChildren;
theChildren.push_back(particle);
theChildren.push_back(otherChild);
//this updates the evolution scale
particle->showerKinematics()->
updateParent(newParent, theChildren,_evolutionScheme,bb.type);
// update the history if needed
_currenttree->updateInitialStateShowerProduct(_progenitor,newParent);
_currenttree->addInitialStateBranching(particle,newParent,otherChild);
// for the reconstruction of kinematics, parent/child
// relationships are according to the branching process:
// now continue the shower
++_nis;
bool emitted = _limitEmissions==0 ?
spaceLikeShower(newParent,beam,type) : false;
if(newParent->spinInfo()) newParent->spinInfo()->develop();
// now reconstruct the momentum
if(!emitted) {
if(_intrinsic.find(_progenitor)==_intrinsic.end()) {
bb.kinematics->updateLast(newParent,ZERO,ZERO);
}
else {
pair<Energy,double> kt=_intrinsic[_progenitor];
bb.kinematics->updateLast(newParent,
kt.first*cos(kt.second),
kt.first*sin(kt.second));
}
}
particle->showerKinematics()->
updateChildren(newParent, theChildren,_evolutionScheme,bb.type);
if(_limitEmissions!=0) {
if(particle->spinInfo()) particle->spinInfo()->develop();
return true;
}
// perform the shower of the final-state particle
timeLikeShower(otherChild,type,Branching(),true);
particle->showerKinematics()->
updateChildren(newParent, theChildren,_evolutionScheme,bb.type);
updateHistory(otherChild);
if(theChildren[1]->spinInfo()) theChildren[1]->spinInfo()->develop();
// return the emitted
if(particle->spinInfo()) particle->spinInfo()->develop();
if(!theChildren.empty()){
particle->showerKinematics()->resetChildren(newParent,theChildren);
}
return true;
}
void QTildeShowerHandler::showerDecay(ShowerTreePtr decay) {
// work out the type of event
currentTree()->xcombPtr(StdXCombPtr());
currentTree()->identifyEventType();
_decayme = HwDecayerBasePtr();
_hardme = HwMEBasePtr();
// find the decayer
// try the normal way if possible
tDMPtr dm = decay->incomingLines().begin()->first->original() ->decayMode();
if(!dm) dm = decay->incomingLines().begin()->first->copy() ->decayMode();
if(!dm) dm = decay->incomingLines().begin()->first->progenitor()->decayMode();
// otherwise make a string and look it up
if(!dm) {
string tag = decay->incomingLines().begin()->first->original()->dataPtr()->name()
+ "->";
OrderedParticles outgoing;
for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
it=decay->outgoingLines().begin();it!=decay->outgoingLines().end();++it) {
if(abs(decay->incomingLines().begin()->first->original()->id()) == ParticleID::t &&
abs(it->first->original()->id())==ParticleID::Wplus &&
decay->treelinks().size() == 1) {
ShowerTreePtr Wtree = decay->treelinks().begin()->first;
for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
it2=Wtree->outgoingLines().begin();it2!=Wtree->outgoingLines().end();++it2) {
outgoing.insert(it2->first->original()->dataPtr());
}
}
else {
outgoing.insert(it->first->original()->dataPtr());
}
}
for(OrderedParticles::const_iterator it=outgoing.begin(); it!=outgoing.end();++it) {
if(it!=outgoing.begin()) tag += ",";
tag +=(**it).name();
}
tag += ";";
dm = findDecayMode(tag);
}
if(dm) _decayme = dynamic_ptr_cast<HwDecayerBasePtr>(dm->decayer());
// set the ShowerTree to be showered
currentTree(decay);
decay->applyTransforms();
hardTree(HardTreePtr());
// generate the showering
doShowering(false,XCPtr());
// if no vetos
// force calculation of spin correlations
SpinPtr spInfo = decay->incomingLines().begin()->first->progenitor()->spinInfo();
if(spInfo) {
if(!spInfo->developed()) spInfo->needsUpdate();
spInfo->develop();
}
}
bool QTildeShowerHandler::spaceLikeDecayShower(tShowerParticlePtr particle,
const ShowerParticle::EvolutionScales & maxScales,
Energy minmass,ShowerInteraction type,
Branching fb) {
// don't do anything if not needed
if(_limitEmissions == 1 || hardOnly() ||
( _limitEmissions == 3 && _nis != 0) ||
( _limitEmissions == 4 && _nfs + _nis != 0) ) {
return false;
}
// generate the emission
ShowerParticleVector children;
// generate the emission
if(!fb.kinematics)
fb = selectSpaceLikeDecayBranching(particle,maxScales,minmass,type,
HardBranchingPtr());
// no emission, return
if(!fb.kinematics) return false;
Branching fc[2];
if(particle->virtualMass()==ZERO)
particle->virtualMass(_progenitor->progenitor()->mass());
fc[0] = Branching();
fc[1] = Branching();
assert(fb.kinematics);
// has emitted
// Assign the shower kinematics to the emitting particle.
particle->showerKinematics(fb.kinematics);
if(fb.kinematics->pT()>progenitor()->highestpT())
progenitor()->highestpT(fb.kinematics->pT());
// create the ShowerParticle objects for the two children
children = createTimeLikeChildren(particle,fb.ids);
// updateChildren the children
particle->showerKinematics()->
updateChildren(particle, children,_evolutionScheme,fb.type);
// select branchings for children
fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass,
type,HardBranchingPtr());
fc[1] = selectTimeLikeBranching (children[1],type,HardBranchingPtr());
// old default
++_nis;
// shower the first particle
_currenttree->updateInitialStateShowerProduct(_progenitor,children[0]);
_currenttree->addInitialStateBranching(particle,children[0],children[1]);
if(fc[0].kinematics) spaceLikeDecayShower(children[0],maxScales,minmass,type,Branching());
// shower the second particle
if(fc[1].kinematics) timeLikeShower(children[1],type,fc[1],true);
updateHistory(children[1]);
// TODO NEED AN UPDATE HERE FOR RECONOPT!=0
// branching has happened
return true;
}
vector<ShowerProgenitorPtr> QTildeShowerHandler::setupShower(bool hard) {
RealEmissionProcessPtr real;
// generate hard me if needed
if(_hardEmission==1) {
real = hardMatrixElementCorrection(hard);
if(real&&!real->outgoing().empty()) setupMECorrection(real);
}
// generate POWHEG hard emission if needed
else if(_hardEmission==2)
hardestEmission(hard);
// set the initial colour partners
setEvolutionPartners(hard,interaction_,false);
// get the particles to be showered
vector<ShowerProgenitorPtr> particlesToShower =
currentTree()->extractProgenitors();
// return the answer
return particlesToShower;
}
void QTildeShowerHandler::setEvolutionPartners(bool hard,ShowerInteraction type,
bool clear) {
// match the particles in the ShowerTree and hardTree
if(hardTree() && !hardTree()->connect(currentTree()))
throw Exception() << "Can't match trees in "
<< "QTildeShowerHandler::setEvolutionPartners()"
<< Exception::eventerror;
// extract the progenitors
vector<ShowerParticlePtr> particles =
currentTree()->extractProgenitorParticles();
// clear the partners if needed
if(clear) {
for(unsigned int ix=0;ix<particles.size();++ix) {
particles[ix]->partner(ShowerParticlePtr());
particles[ix]->clearPartners();
}
}
// sort out the colour partners
if(hardTree()) {
// find the partner
for(unsigned int ix=0;ix<particles.size();++ix) {
tShowerParticlePtr partner = hardTree()->particles()[particles[ix]]->branchingParticle()->partner();
if(!partner) continue;
for(map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator
it=hardTree()->particles().begin();
it!=hardTree()->particles().end();++it) {
if(it->second->branchingParticle()==partner) {
particles[ix]->partner(it->first);
break;
}
}
if(!particles[ix]->partner())
throw Exception() << "Can't match partners in "
<< "QTildeShowerHandler::setEvolutionPartners()"
<< Exception::eventerror;
}
}
// Set the initial evolution scales
partnerFinder()->
setInitialEvolutionScales(particles,!hard,interaction_,!_hardtree);
if(hardTree() && _hardPOWHEG) {
bool tooHard=false;
map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator
eit=hardTree()->particles().end();
for(unsigned int ix=0;ix<particles.size();++ix) {
map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator
mit = hardTree()->particles().find(particles[ix]);
Energy hardScale(ZERO);
ShowerPartnerType type(ShowerPartnerType::Undefined);
// final-state
if(particles[ix]->isFinalState()) {
if(mit!= eit && !mit->second->children().empty()) {
hardScale = mit->second->scale();
type = mit->second->type();
}
}
// initial-state
else {
if(mit!= eit && mit->second->parent()) {
hardScale = mit->second->parent()->scale();
type = mit->second->parent()->type();
}
}
if(type!=ShowerPartnerType::Undefined) {
if(type==ShowerPartnerType::QED) {
tooHard |= particles[ix]->scales().QED_noAO<hardScale;
}
else if(type==ShowerPartnerType::QCDColourLine) {
tooHard |= particles[ix]->scales().QCD_c_noAO<hardScale;
}
else if(type==ShowerPartnerType::QCDAntiColourLine) {
tooHard |= particles[ix]->scales().QCD_ac_noAO<hardScale;
}
else if(type==ShowerPartnerType::EW) {
tooHard |= particles[ix]->scales().EW<hardScale;
}
}
}
if(tooHard) convertHardTree(hard,type);
}
}
void QTildeShowerHandler::updateHistory(tShowerParticlePtr particle) {
if(!particle->children().empty()) {
ShowerParticleVector theChildren;
for(unsigned int ix=0;ix<particle->children().size();++ix) {
ShowerParticlePtr part = dynamic_ptr_cast<ShowerParticlePtr>
(particle->children()[ix]);
theChildren.push_back(part);
}
// update the history if needed
if(particle==_currenttree->getFinalStateShowerProduct(_progenitor))
_currenttree->updateFinalStateShowerProduct(_progenitor,
particle,theChildren);
_currenttree->addFinalStateBranching(particle,theChildren);
for(unsigned int ix=0;ix<theChildren.size();++ix)
updateHistory(theChildren[ix]);
}
}
bool QTildeShowerHandler::startTimeLikeShower(ShowerInteraction type) {
// initialize basis vectors etc
if(!progenitor()->progenitor()->partner()) return false;
progenitor()->progenitor()->initializeFinalState();
if(hardTree()) {
map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator
eit=hardTree()->particles().end(),
mit = hardTree()->particles().find(progenitor()->progenitor());
if( mit != eit && !mit->second->children().empty() ) {
bool output=truncatedTimeLikeShower(progenitor()->progenitor(),
mit->second ,type,Branching(),true);
if(output) updateHistory(progenitor()->progenitor());
return output;
}
}
// do the shower
bool output = hardOnly() ? false :
timeLikeShower(progenitor()->progenitor() ,type,Branching(),true) ;
if(output) updateHistory(progenitor()->progenitor());
return output;
}
bool QTildeShowerHandler::startSpaceLikeShower(PPtr parent, ShowerInteraction type) {
// initialise the basis vectors
if(!progenitor()->progenitor()->partner()) return false;
progenitor()->progenitor()->initializeInitialState(parent);
if(hardTree()) {
map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator
eit =hardTree()->particles().end(),
mit = hardTree()->particles().find(progenitor()->progenitor());
if( mit != eit && mit->second->parent() ) {
return truncatedSpaceLikeShower( progenitor()->progenitor(),
parent, mit->second->parent(), type );
}
}
// perform the shower
return hardOnly() ? false :
spaceLikeShower(progenitor()->progenitor(),parent,type);
}
bool QTildeShowerHandler::
startSpaceLikeDecayShower(const ShowerParticle::EvolutionScales & maxScales,
Energy minimumMass,ShowerInteraction type) {
// set up the particle basis vectors
if(!progenitor()->progenitor()->partner()) return false;
progenitor()->progenitor()->initializeDecay();
if(hardTree()) {
map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator
eit =hardTree()->particles().end(),
mit = hardTree()->particles().find(progenitor()->progenitor());
if( mit != eit && mit->second->parent() ) {
HardBranchingPtr branch=mit->second;
while(branch->parent()) branch=branch->parent();
return truncatedSpaceLikeDecayShower(progenitor()->progenitor(),maxScales,
minimumMass, branch ,type, Branching());
}
}
// perform the shower
return hardOnly() ? false :
spaceLikeDecayShower(progenitor()->progenitor(),maxScales,minimumMass,type,Branching());
}
bool QTildeShowerHandler::timeLikeVetoed(const Branching & fb,
ShowerParticlePtr particle) {
// work out type of interaction
ShowerInteraction type = convertInteraction(fb.type);
// check whether emission was harder than largest pt of hard subprocess
if ( restrictPhasespace() && fb.kinematics->pT() > _progenitor->maxHardPt() )
return true;
// soft matrix element correction veto
if( softMEC()) {
if(_hardme && _hardme->hasMECorrection()) {
if(_hardme->softMatrixElementVeto(particle,
_progenitor->progenitor(),
particle->isFinalState(),
_progenitor->highestpT(),
fb.ids, fb.kinematics->z(),
fb.kinematics->scale(),
fb.kinematics->pT()))
return true;
}
else if(_decayme && _decayme->hasMECorrection()) {
if(_decayme->softMatrixElementVeto(particle,
_progenitor->progenitor(),
particle->isFinalState(),
_progenitor->highestpT(),
fb.ids, fb.kinematics->z(),
fb.kinematics->scale(),
fb.kinematics->pT()))
return true;
}
}
// veto on maximum pt
if(fb.kinematics->pT()>_progenitor->maximumpT(type)) return true;
// general vetos
if (fb.kinematics && !_vetoes.empty()) {
bool vetoed=false;
for (vector<ShowerVetoPtr>::iterator v = _vetoes.begin();
v != _vetoes.end(); ++v) {
bool test = (**v).vetoTimeLike(_progenitor,particle,fb,currentTree());
switch((**v).vetoType()) {
case ShowerVeto::Emission:
vetoed |= test;
break;
case ShowerVeto::Shower:
if(test) throw VetoShower();
break;
case ShowerVeto::Event:
if(test) throw Veto();
break;
}
}
if(vetoed) return true;
}
if ( firstInteraction() &&
profileScales() ) {
double weight =
profileScales()->
hardScaleProfile(_progenitor->hardScale(),fb.kinematics->pT());
if ( UseRandom::rnd() > weight )
return true;
}
return false;
}
bool QTildeShowerHandler::spaceLikeVetoed(const Branching & bb,
ShowerParticlePtr particle) {
// work out type of interaction
ShowerInteraction type = convertInteraction(bb.type);
// check whether emission was harder than largest pt of hard subprocess
if (restrictPhasespace() && bb.kinematics->pT() > _progenitor->maxHardPt())
return true;
// apply the soft correction
if( softMEC() && _hardme && _hardme->hasMECorrection() ) {
if(_hardme->softMatrixElementVeto(particle,
_progenitor->progenitor(),
particle->isFinalState(),
_progenitor->highestpT(),
bb.ids, bb.kinematics->z(),
bb.kinematics->scale(),
bb.kinematics->pT()))
return true;
}
// the more general vetos
// check vs max pt for the shower
if(bb.kinematics->pT()>_progenitor->maximumpT(type)) return true;
if (!_vetoes.empty()) {
bool vetoed=false;
for (vector<ShowerVetoPtr>::iterator v = _vetoes.begin();
v != _vetoes.end(); ++v) {
bool test = (**v).vetoSpaceLike(_progenitor,particle,bb,currentTree());
switch ((**v).vetoType()) {
case ShowerVeto::Emission:
vetoed |= test;
break;
case ShowerVeto::Shower:
if(test) throw VetoShower();
break;
case ShowerVeto::Event:
if(test) throw Veto();
break;
}
}
if (vetoed) return true;
}
if ( firstInteraction() &&
profileScales() ) {
double weight =
profileScales()->
hardScaleProfile(_progenitor->hardScale(),bb.kinematics->pT());
if ( UseRandom::rnd() > weight )
return true;
}
return false;
}
bool QTildeShowerHandler::spaceLikeDecayVetoed( const Branching & fb,
ShowerParticlePtr particle) {
// work out type of interaction
ShowerInteraction type = convertInteraction(fb.type);
// apply the soft correction
if( softMEC() && _decayme && _decayme->hasMECorrection() ) {
if(_decayme->softMatrixElementVeto(particle,
_progenitor->progenitor(),
particle->isFinalState(),
_progenitor->highestpT(),
fb.ids, fb.kinematics->z(),
fb.kinematics->scale(),
fb.kinematics->pT()))
return true;
}
// veto on hardest pt in the shower
if(fb.kinematics->pT()> _progenitor->maximumpT(type)) return true;
// general vetos
if (!_vetoes.empty()) {
bool vetoed=false;
for (vector<ShowerVetoPtr>::iterator v = _vetoes.begin();
v != _vetoes.end(); ++v) {
bool test = (**v).vetoSpaceLike(_progenitor,particle,fb,currentTree());
switch((**v).vetoType()) {
case ShowerVeto::Emission:
vetoed |= test;
break;
case ShowerVeto::Shower:
if(test) throw VetoShower();
break;
case ShowerVeto::Event:
if(test) throw Veto();
break;
}
if (vetoed) return true;
}
}
return false;
}
void QTildeShowerHandler::hardestEmission(bool hard) {
HardTreePtr ISRTree;
// internal POWHEG in production or decay
if( (( _hardme && _hardme->hasPOWHEGCorrection()!=0 ) ||
( _decayme && _decayme->hasPOWHEGCorrection()!=0 ) ) ) {
RealEmissionProcessPtr real;
unsigned int type(0);
// production
if(_hardme) {
assert(hard);
real = _hardme->generateHardest( currentTree()->perturbativeProcess(),
interaction_);
type = _hardme->hasPOWHEGCorrection();
}
// decay
else {
assert(!hard);
real = _decayme->generateHardest( currentTree()->perturbativeProcess() );
type = _decayme->hasPOWHEGCorrection();
}
if(real) {
// set up ther hard tree
if(!real->outgoing().empty()) _hardtree = new_ptr(HardTree(real));
// set up the vetos
currentTree()->setVetoes(real->pT(),type);
}
// store initial state POWHEG radiation
if(_hardtree && _hardme && _hardme->hasPOWHEGCorrection()==1)
ISRTree = _hardtree;
}
else if (hard) {
// Get minimum pT cutoff used in shower approximation
Energy maxpt = 1.*GeV;
if ( currentTree()->showerApproximation() ) {
int colouredIn = 0;
int colouredOut = 0;
for( map< ShowerProgenitorPtr, tShowerParticlePtr >::iterator it
= currentTree()->outgoingLines().begin();
it != currentTree()->outgoingLines().end(); ++it ) {
if( it->second->coloured() ) ++colouredOut;
}
for( map< ShowerProgenitorPtr, ShowerParticlePtr >::iterator it
= currentTree()->incomingLines().begin();
it != currentTree()->incomingLines().end(); ++it ) {
if( it->second->coloured() ) ++colouredIn;
}
if ( currentTree()->showerApproximation()->ffPtCut() == currentTree()->showerApproximation()->fiPtCut() &&
currentTree()->showerApproximation()->ffPtCut() == currentTree()->showerApproximation()->iiPtCut() )
maxpt = currentTree()->showerApproximation()->ffPtCut();
else if ( colouredIn == 2 && colouredOut == 0 )
maxpt = currentTree()->showerApproximation()->iiPtCut();
else if ( colouredIn == 0 && colouredOut > 1 )
maxpt = currentTree()->showerApproximation()->ffPtCut();
else if ( colouredIn == 2 && colouredOut == 1 )
maxpt = min(currentTree()->showerApproximation()->iiPtCut(), currentTree()->showerApproximation()->fiPtCut());
else if ( colouredIn == 1 && colouredOut > 1 )
maxpt = min(currentTree()->showerApproximation()->ffPtCut(), currentTree()->showerApproximation()->fiPtCut());
else
maxpt = min(min(currentTree()->showerApproximation()->iiPtCut(), currentTree()->showerApproximation()->fiPtCut()),
currentTree()->showerApproximation()->ffPtCut());
}
// Generate hardtree from born and real emission subprocesses
_hardtree = generateCKKW(currentTree());
// Find transverse momentum of hardest emission
if (_hardtree){
for(set<HardBranchingPtr>::iterator it=_hardtree->branchings().begin();
it!=_hardtree->branchings().end();++it) {
if ((*it)->parent() && (*it)->status()==HardBranching::Incoming)
maxpt=(*it)->branchingParticle()->momentum().perp();
if ((*it)->children().size()==2 && (*it)->status()==HardBranching::Outgoing){
if ((*it)->branchingParticle()->id()!=21 &&
abs((*it)->branchingParticle()->id())>5 ){
if ((*it)->children()[0]->branchingParticle()->id()==21 ||
abs((*it)->children()[0]->branchingParticle()->id())<6)
maxpt=(*it)->children()[0]->branchingParticle()->momentum().perp();
else if ((*it)->children()[1]->branchingParticle()->id()==21 ||
abs((*it)->children()[1]->branchingParticle()->id())<6)
maxpt=(*it)->children()[1]->branchingParticle()->momentum().perp();
}
else {
if ( abs((*it)->branchingParticle()->id())<6){
if (abs((*it)->children()[0]->branchingParticle()->id())<6)
maxpt = (*it)->children()[1]->branchingParticle()->momentum().perp();
else
maxpt = (*it)->children()[0]->branchingParticle()->momentum().perp();
}
else maxpt = (*it)->children()[1]->branchingParticle()->momentum().perp();
}
}
}
}
// Hardest (pt) emission should be the first powheg emission.
maxpt=min(sqrt(lastXCombPtr()->lastShowerScale()),maxpt);
// set maximum pT for subsequent emissions from S events
if ( currentTree()->isPowhegSEvent() ) {
for( map< ShowerProgenitorPtr, tShowerParticlePtr >::iterator it
= currentTree()->outgoingLines().begin();
it != currentTree()->outgoingLines().end(); ++it ) {
if( ! it->second->coloured() ) continue;
it->first->maximumpT(maxpt, ShowerInteraction::QCD );
}
for( map< ShowerProgenitorPtr, ShowerParticlePtr >::iterator it
= currentTree()->incomingLines().begin();
it != currentTree()->incomingLines().end(); ++it ) {
if( ! it->second->coloured() ) continue;
it->first->maximumpT(maxpt, ShowerInteraction::QCD );
}
}
}
else
_hardtree = generateCKKW(currentTree());
// if hard me doesn't have a FSR powheg
// correction use decay powheg correction
if (_hardme && _hardme->hasPOWHEGCorrection()<2) {
addFSRUsingDecayPOWHEG(ISRTree);
}
// connect the trees
if(_hardtree) {
connectTrees(currentTree(),_hardtree,hard);
}
}
void QTildeShowerHandler::addFSRUsingDecayPOWHEG(HardTreePtr ISRTree) {
// check for intermediate colour singlet resonance
const ParticleVector inter = _hardme->subProcess()->intermediates();
if (inter.size()!=1 || inter[0]->momentum().m2()/GeV2 < 0 ||
inter[0]->dataPtr()->iColour()!=PDT::Colour0) {
return;
}
// ignore cases where outgoing particles are not coloured
map<ShowerProgenitorPtr, tShowerParticlePtr > out = currentTree()->outgoingLines();
if (out.size() != 2 ||
out. begin()->second->dataPtr()->iColour()==PDT::Colour0 ||
out.rbegin()->second->dataPtr()->iColour()==PDT::Colour0) {
return;
}
// look up decay mode
tDMPtr dm;
string tag;
string inParticle = inter[0]->dataPtr()->name() + "->";
vector<string> outParticles;
outParticles.push_back(out.begin ()->first->progenitor()->dataPtr()->name());
outParticles.push_back(out.rbegin()->first->progenitor()->dataPtr()->name());
for (int it=0; it<2; ++it){
tag = inParticle + outParticles[it] + "," + outParticles[(it+1)%2] + ";";
dm = generator()->findDecayMode(tag);
if(dm) break;
}
// get the decayer
HwDecayerBasePtr decayer;
if(dm) decayer = dynamic_ptr_cast<HwDecayerBasePtr>(dm->decayer());
// check if decayer has a FSR POWHEG correction
if (!decayer || decayer->hasPOWHEGCorrection()<2) {
return;
}
// generate the hardest emission
// create RealEmissionProcess
PPtr in = new_ptr(*inter[0]);
RealEmissionProcessPtr newProcess(new_ptr(RealEmissionProcess()));
newProcess->bornIncoming().push_back(in);
newProcess->bornOutgoing().push_back(out.begin ()->first->progenitor());
newProcess->bornOutgoing().push_back(out.rbegin()->first->progenitor());
// generate the FSR
newProcess = decayer->generateHardest(newProcess);
HardTreePtr FSRTree;
if(newProcess) {
// set up ther hard tree
if(!newProcess->outgoing().empty()) FSRTree = new_ptr(HardTree(newProcess));
// set up the vetos
currentTree()->setVetoes(newProcess->pT(),2);
}
if(!FSRTree) return;
// if there is no ISRTree make _hardtree from FSRTree
if (!ISRTree){
vector<HardBranchingPtr> inBranch,hardBranch;
for(map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator
cit =currentTree()->incomingLines().begin();
cit!=currentTree()->incomingLines().end();++cit ) {
inBranch.push_back(new_ptr(HardBranching(cit->second,SudakovPtr(),
HardBranchingPtr(),
HardBranching::Incoming)));
inBranch.back()->beam(cit->first->original()->parents()[0]);
hardBranch.push_back(inBranch.back());
}
if(inBranch[0]->branchingParticle()->dataPtr()->coloured()) {
inBranch[0]->colourPartner(inBranch[1]);
inBranch[1]->colourPartner(inBranch[0]);
}
for(set<HardBranchingPtr>::iterator it=FSRTree->branchings().begin();
it!=FSRTree->branchings().end();++it) {
if((**it).branchingParticle()->id()!=in->id())
hardBranch.push_back(*it);
}
hardBranch[2]->colourPartner(hardBranch[3]);
hardBranch[3]->colourPartner(hardBranch[2]);
HardTreePtr newTree = new_ptr(HardTree(hardBranch,inBranch,
ShowerInteraction::QCD));
_hardtree = newTree;
}
// Otherwise modify the ISRTree to include the emission in FSRTree
else {
vector<tShowerParticlePtr> FSROut, ISROut;
set<HardBranchingPtr>::iterator itFSR, itISR;
// get outgoing particles
for(itFSR =FSRTree->branchings().begin();
itFSR!=FSRTree->branchings().end();++itFSR){
if ((**itFSR).status()==HardBranching::Outgoing)
FSROut.push_back((*itFSR)->branchingParticle());
}
for(itISR =ISRTree->branchings().begin();
itISR!=ISRTree->branchings().end();++itISR){
if ((**itISR).status()==HardBranching::Outgoing)
ISROut.push_back((*itISR)->branchingParticle());
}
// find COM frame formed by outgoing particles
LorentzRotation eventFrameFSR, eventFrameISR;
eventFrameFSR = ((FSROut[0]->momentum()+FSROut[1]->momentum()).findBoostToCM());
eventFrameISR = ((ISROut[0]->momentum()+ISROut[1]->momentum()).findBoostToCM());
// find rotation between ISR and FSR frames
int j=0;
if (ISROut[0]->id()!=FSROut[0]->id()) j=1;
eventFrameISR.rotateZ( (eventFrameFSR*FSROut[0]->momentum()).phi()-
(eventFrameISR*ISROut[j]->momentum()).phi() );
eventFrameISR.rotateY( (eventFrameFSR*FSROut[0]->momentum()).theta()-
(eventFrameISR*ISROut[j]->momentum()).theta() );
eventFrameISR.invert();
for (itFSR=FSRTree->branchings().begin();
itFSR!=FSRTree->branchings().end();++itFSR){
if ((**itFSR).branchingParticle()->id()==in->id()) continue;
for (itISR =ISRTree->branchings().begin();
itISR!=ISRTree->branchings().end();++itISR){
if ((**itISR).status()==HardBranching::Incoming) continue;
if ((**itFSR).branchingParticle()->id()==
(**itISR).branchingParticle()->id()){
// rotate FSRTree particle to ISRTree event frame
(**itISR).branchingParticle()->setMomentum(eventFrameISR*
eventFrameFSR*
(**itFSR).branchingParticle()->momentum());
(**itISR).branchingParticle()->rescaleMass();
// add the children of the FSRTree particles to the ISRTree
if(!(**itFSR).children().empty()){
(**itISR).addChild((**itFSR).children()[0]);
(**itISR).addChild((**itFSR).children()[1]);
// rotate momenta to ISRTree event frame
(**itISR).children()[0]->branchingParticle()->setMomentum(eventFrameISR*
eventFrameFSR*
(**itFSR).children()[0]->branchingParticle()->momentum());
(**itISR).children()[1]->branchingParticle()->setMomentum(eventFrameISR*
eventFrameFSR*
(**itFSR).children()[1]->branchingParticle()->momentum());
}
}
}
}
_hardtree = ISRTree;
}
}
bool QTildeShowerHandler::truncatedTimeLikeShower(tShowerParticlePtr particle,
HardBranchingPtr branch,
ShowerInteraction type,
Branching fb, bool first) {
// select a branching if we don't have one
if(!fb.kinematics)
fb = selectTimeLikeBranching(particle,type,branch);
// must be an emission, the forced one it not a truncated one
assert(fb.kinematics);
ShowerParticleVector children;
Branching fc[2] = {Branching(),Branching()};
// Assign the shower kinematics to the emitting particle.
particle->showerKinematics(fb.kinematics);
if(fb.kinematics->pT()>progenitor()->highestpT())
progenitor()->highestpT(fb.kinematics->pT());
// create the children
children = createTimeLikeChildren(particle,fb.ids);
// update the children
particle->showerKinematics()->
updateChildren(particle, children,_evolutionScheme,fb.type);
// select branchings for children
if(!fc[0].kinematics) {
// select branching for first particle
if(!fb.hard && fb.iout ==1 )
fc[0] = selectTimeLikeBranching(children[0],type,branch);
else if(fb.hard && !branch->children()[0]->children().empty() )
fc[0] = selectTimeLikeBranching(children[0],type,branch->children()[0]);
else
fc[0] = selectTimeLikeBranching(children[0],type,HardBranchingPtr());
}
// select branching for the second particle
if(!fc[1].kinematics) {
// select branching for first particle
if(!fb.hard && fb.iout ==2 )
fc[1] = selectTimeLikeBranching(children[1],type,branch);
else if(fb.hard && !branch->children()[1]->children().empty() )
fc[1] = selectTimeLikeBranching(children[1],type,branch->children()[1]);
else
fc[1] = selectTimeLikeBranching(children[1],type,HardBranchingPtr());
}
// shower the first particle
if(fc[0].kinematics) {
// the parent has truncated emission and following line
if(!fb.hard && fb.iout == 1)
truncatedTimeLikeShower(children[0],branch,type,fc[0],false);
// hard emission and subsquent hard emissions
else if(fb.hard && !branch->children()[0]->children().empty() )
truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false);
// normal shower
else
timeLikeShower(children[0],type,fc[0],false);
}
if(children[0]->spinInfo()) children[0]->spinInfo()->develop();
// shower the second particle
if(fc[1].kinematics) {
// the parent has truncated emission and following line
if(!fb.hard && fb.iout == 2)
truncatedTimeLikeShower(children[1],branch,type,fc[1],false);
// hard emission and subsquent hard emissions
else if(fb.hard && !branch->children()[1]->children().empty() )
truncatedTimeLikeShower(children[1],branch->children()[1],type,fc[1],false);
else
timeLikeShower(children[1],type,fc[1],false);
}
if(children[1]->spinInfo()) children[1]->spinInfo()->develop();
// branching has happened
particle->showerKinematics()->updateParent(particle, children,_evolutionScheme,fb.type);
if(first&&!children.empty())
particle->showerKinematics()->resetChildren(particle,children);
if(particle->spinInfo()) particle->spinInfo()->develop();
// TODO NEED AN UPDATE HERE FOR RECONOPT!=0 ?
return true;
}
bool QTildeShowerHandler::truncatedSpaceLikeShower(tShowerParticlePtr particle, PPtr beam,
HardBranchingPtr branch,
ShowerInteraction type) {
tcPDFPtr pdf;
if(firstPDF().particle() == beamParticle())
pdf = firstPDF().pdf();
if(secondPDF().particle() == beamParticle())
pdf = secondPDF().pdf();
Energy freeze = pdfFreezingScale();
Branching bb;
// parameters of the force branching
double z(0.);
HardBranchingPtr timelike;
for( unsigned int ix = 0; ix < branch->children().size(); ++ix ) {
if( branch->children()[ix]->status() ==HardBranching::Outgoing) {
timelike = branch->children()[ix];
}
if( branch->children()[ix]->status() ==HardBranching::Incoming )
z = branch->children()[ix]->z();
}
// generate truncated branching
tcPDPtr part[2];
if(z>=0.&&z<=1.) {
while (true) {
if( !isTruncatedShowerON() || hardOnly() ) break;
bb = splittingGenerator()->chooseBackwardBranching( *particle,
beam, 1., beamParticle(),
type , pdf,freeze);
if( !bb.kinematics || bb.kinematics->scale() < branch->scale() ) {
bb = Branching();
break;
}
// particles as in Sudakov form factor
part[0] = bb.ids[0];
part[1] = bb.ids[2];
double zsplit = bb.kinematics->z();
// apply the vetos for the truncated shower
// if doesn't carry most of momentum
ShowerInteraction type2 = convertInteraction(bb.type);
if(type2==branch->sudakov()->interactionType() &&
zsplit < 0.5) {
particle->vetoEmission(bb.type,bb.kinematics->scale());
continue;
}
// others
if( part[0]->id() != particle->id() || // if particle changes type
bb.kinematics->pT() > progenitor()->maximumpT(type2) || // pt veto
bb.kinematics->scale() < branch->scale()) { // angular ordering veto
particle->vetoEmission(bb.type,bb.kinematics->scale());
continue;
}
// and those from the base class
if(spaceLikeVetoed(bb,particle)) {
particle->vetoEmission(bb.type,bb.kinematics->scale());
continue;
}
break;
}
}
if( !bb.kinematics ) {
//do the hard emission
ShoKinPtr kinematics = new_ptr(IS_QTildeShowerKinematics1to2(
branch->scale(), z, branch->phi(),
branch->children()[0]->pT(), branch->sudakov()
));
// assign the splitting function and shower kinematics
particle->showerKinematics( kinematics );
if(kinematics->pT()>progenitor()->highestpT())
progenitor()->highestpT(kinematics->pT());
// For the time being we are considering only 1->2 branching
// Now create the actual particles, make the otherChild a final state
// particle, while the newParent is not
ShowerParticlePtr newParent =
new_ptr( ShowerParticle( branch->branchingParticle()->dataPtr(), false ) );
ShowerParticlePtr otherChild =
new_ptr( ShowerParticle( timelike->branchingParticle()->dataPtr(),
true, true ) );
ShowerParticleVector theChildren;
theChildren.push_back( particle );
theChildren.push_back( otherChild );
particle->showerKinematics()->
updateParent( newParent, theChildren,_evolutionScheme, branch->type());
// update the history if needed
currentTree()->updateInitialStateShowerProduct( progenitor(), newParent );
currentTree()->addInitialStateBranching( particle, newParent, otherChild );
// for the reconstruction of kinematics, parent/child
// relationships are according to the branching process:
// now continue the shower
bool emitted=false;
if(!hardOnly()) {
if( branch->parent() ) {
emitted = truncatedSpaceLikeShower( newParent, beam, branch->parent() , type);
}
else {
emitted = spaceLikeShower( newParent, beam , type);
}
}
if( !emitted ) {
if( intrinsicpT().find( progenitor() ) == intrinsicpT().end() ) {
kinematics->updateLast( newParent, ZERO, ZERO );
}
else {
pair<Energy,double> kt = intrinsicpT()[progenitor()];
kinematics->updateLast( newParent,
kt.first*cos( kt.second ),
kt.first*sin( kt.second ) );
}
}
particle->showerKinematics()->
updateChildren( newParent, theChildren,_evolutionScheme,bb.type);
if(hardOnly()) return true;
// perform the shower of the final-state particle
if( timelike->children().empty() ) {
timeLikeShower( otherChild , type,Branching(),true);
}
else {
truncatedTimeLikeShower( otherChild, timelike , type,Branching(), true);
}
updateHistory(otherChild);
// return the emitted
return true;
}
// assign the splitting function and shower kinematics
particle->showerKinematics( bb.kinematics );
if(bb.kinematics->pT()>progenitor()->highestpT())
progenitor()->highestpT(bb.kinematics->pT());
// For the time being we are considering only 1->2 branching
// Now create the actual particles, make the otherChild a final state
// particle, while the newParent is not
ShowerParticlePtr newParent = new_ptr( ShowerParticle( part[0], false ) );
ShowerParticlePtr otherChild = new_ptr( ShowerParticle( part[1], true, true ) );
ShowerParticleVector theChildren;
theChildren.push_back( particle );
theChildren.push_back( otherChild );
particle->showerKinematics()->
updateParent( newParent, theChildren,_evolutionScheme, bb.type);
// update the history if needed
currentTree()->updateInitialStateShowerProduct( progenitor(), newParent );
currentTree()->addInitialStateBranching( particle, newParent, otherChild );
// for the reconstruction of kinematics, parent/child
// relationships are according to the branching process:
// now continue the shower
bool emitted = truncatedSpaceLikeShower( newParent, beam, branch,type);
// now reconstruct the momentum
if( !emitted ) {
if( intrinsicpT().find( progenitor() ) == intrinsicpT().end() ) {
bb.kinematics->updateLast( newParent, ZERO, ZERO );
}
else {
pair<Energy,double> kt = intrinsicpT()[ progenitor() ];
bb.kinematics->updateLast( newParent,
kt.first*cos( kt.second ),
kt.first*sin( kt.second ) );
}
}
particle->showerKinematics()->
updateChildren( newParent, theChildren,_evolutionScheme, bb.type);
// perform the shower of the final-state particle
timeLikeShower( otherChild , type,Branching(),true);
updateHistory(otherChild);
// return the emitted
return true;
}
bool QTildeShowerHandler::
truncatedSpaceLikeDecayShower(tShowerParticlePtr particle,
const ShowerParticle::EvolutionScales & maxScales,
Energy minmass, HardBranchingPtr branch,
ShowerInteraction type, Branching fb) {
// select a branching if we don't have one
if(!fb.kinematics)
fb = selectSpaceLikeDecayBranching(particle,maxScales,minmass,type,branch);
// must be an emission, the forced one it not a truncated one
assert(fb.kinematics);
ShowerParticleVector children;
Branching fc[2]={Branching(),Branching()};
// Assign the shower kinematics to the emitting particle.
particle->showerKinematics(fb.kinematics);
if(fb.kinematics->pT()>progenitor()->highestpT())
progenitor()->highestpT(fb.kinematics->pT());
// create the ShowerParticle objects for the two children
children = createTimeLikeChildren(particle,fb.ids);
// updateChildren the children
particle->showerKinematics()->
updateChildren(particle, children,_evolutionScheme, fb.type);
// select branchings for children
if(!fc[0].kinematics) {
if(children[0]->id()==particle->id()) {
// select branching for first particle
if(!fb.hard)
fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass,type,branch);
else if(fb.hard && ! branch->children()[0]->children().empty() )
fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass,type,
branch->children()[0]);
else
fc[0] = selectSpaceLikeDecayBranching(children[0],maxScales,minmass,type,
HardBranchingPtr());
}
else {
// select branching for first particle
if(fb.hard && !branch->children()[0]->children().empty() )
fc[0] = selectTimeLikeBranching(children[0],type,branch->children()[0]);
else
fc[0] = selectTimeLikeBranching(children[0],type,HardBranchingPtr());
}
}
// select branching for the second particle
if(!fc[1].kinematics) {
if(children[1]->id()==particle->id()) {
// select branching for first particle
if(!fb.hard)
fc[1] = selectSpaceLikeDecayBranching(children[1],maxScales,minmass,type,branch);
else if(fb.hard && ! branch->children()[1]->children().empty() )
fc[1] = selectSpaceLikeDecayBranching(children[1],maxScales,minmass,type,
branch->children()[1]);
else
fc[1] = selectSpaceLikeDecayBranching(children[1],maxScales,minmass,type,
HardBranchingPtr());
}
else {
if(fb.hard && !branch->children()[1]->children().empty() )
fc[1] = selectTimeLikeBranching(children[1],type,branch->children()[1]);
else
fc[1] = selectTimeLikeBranching(children[1],type,HardBranchingPtr());
}
}
// old default
// update the history if needed
currentTree()->updateInitialStateShowerProduct(progenitor(),children[0]);
currentTree()->addInitialStateBranching(particle,children[0],children[1]);
// shower the first particle
if(fc[0].kinematics) {
if(children[0]->id()==particle->id()) {
if(!fb.hard)
truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
branch,type,fc[0]);
else if(fb.hard && ! branch->children()[0]->children().empty() )
truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
branch->children()[0],type,fc[0]);
else
spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[0]);
}
else {
if(fb.hard && !branch->children()[0]->children().empty() )
truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[0],false);
// normal shower
else
timeLikeShower(children[0],type,fc[0],false);
}
}
// shower the second particle
if(fc[1].kinematics) {
if(children[0]->id()==particle->id()) {
if(!fb.hard)
truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
branch,type,fc[1]);
else if(fb.hard && ! branch->children()[0]->children().empty() )
truncatedSpaceLikeDecayShower( children[0],maxScales,minmass,
branch->children()[0],type,fc[1]);
else
spaceLikeDecayShower( children[0],maxScales,minmass,type,fc[1]);
}
else {
if(fb.hard && !branch->children()[0]->children().empty() )
truncatedTimeLikeShower(children[0],branch->children()[0],type,fc[1],false);
// normal shower
else
timeLikeShower(children[0],type,fc[1],false);
}
}
updateHistory(children[1]);
// TODO DO WE NEED A CHECK IF RECONPT !=0
return true;
}
void QTildeShowerHandler::connectTrees(ShowerTreePtr showerTree,
HardTreePtr hardTree, bool hard ) {
ShowerParticleVector particles;
// find the Sudakovs
for(set<HardBranchingPtr>::iterator cit=hardTree->branchings().begin();
cit!=hardTree->branchings().end();++cit) {
// Sudakovs for ISR
if((**cit).parent()&&(**cit).status()==HardBranching::Incoming) {
++_nis;
array<long,3> br;
br[0] = (**cit).parent()->branchingParticle()->id();
br[1] = (**cit). branchingParticle()->id();
br[2] = (**cit).parent()->children()[0]==*cit ?
(**cit).parent()->children()[1]->branchingParticle()->id() :
(**cit).parent()->children()[0]->branchingParticle()->id();
BranchingList branchings = splittingGenerator()->initialStateBranchings();
if(br[1]<0&&br[0]==br[1]) {
br[0] = abs(br[0]);
br[1] = abs(br[1]);
}
else if(br[1]<0) {
br[1] = -br[1];
br[2] = -br[2];
}
long index = abs(br[1]);
SudakovPtr sudakov;
for(BranchingList::const_iterator cjt = branchings.lower_bound(index);
cjt != branchings.upper_bound(index); ++cjt ) {
IdList ids = cjt->second.particles;
if(ids[0]->id()==br[0]&&ids[1]->id()==br[1]&&ids[2]->id()==br[2]) {
sudakov=cjt->second.sudakov;
break;
}
}
if(!sudakov) throw Exception() << "Can't find Sudakov for the hard emission in "
<< "QTildeShowerHandler::connectTrees() for ISR"
<< Exception::runerror;
(**cit).parent()->sudakov(sudakov);
}
// Sudakovs for FSR
else if(!(**cit).children().empty()) {
++_nfs;
array<long,3> br;
br[0] = (**cit) .branchingParticle()->id();
br[1] = (**cit).children()[0]->branchingParticle()->id();
br[2] = (**cit).children()[1]->branchingParticle()->id();
BranchingList branchings = splittingGenerator()->finalStateBranchings();
if(br[0]<0) {
br[0] = abs(br[0]);
br[1] = abs(br[1]);
br[2] = abs(br[2]);
}
long index = br[0];
SudakovPtr sudakov;
for(BranchingList::const_iterator cjt = branchings.lower_bound(index);
cjt != branchings.upper_bound(index); ++cjt ) {
IdList ids = cjt->second.particles;
if(ids[0]->id()==br[0]&&ids[1]->id()==br[1]&&ids[2]->id()==br[2]) {
sudakov=cjt->second.sudakov;
break;
}
}
if(!sudakov) {
throw Exception() << "Can't find Sudakov for the hard emission in "
<< "QTildeShowerHandler::connectTrees()"
<< Exception::runerror;
}
(**cit).sudakov(sudakov);
}
}
// calculate the evolution scale
for(set<HardBranchingPtr>::iterator cit=hardTree->branchings().begin();
cit!=hardTree->branchings().end();++cit) {
particles.push_back((*cit)->branchingParticle());
}
partnerFinder()->
setInitialEvolutionScales(particles,!hard,interaction_,true);
hardTree->partnersSet(true);
// inverse reconstruction
if(hard) {
kinematicsReconstructor()->
deconstructHardJets(hardTree,interaction_);
}
else
kinematicsReconstructor()->
deconstructDecayJets(hardTree,interaction_);
// now reset the momenta of the showering particles
vector<ShowerProgenitorPtr> particlesToShower=showerTree->extractProgenitors();
// match them
map<ShowerProgenitorPtr,HardBranchingPtr> partners;
for(set<HardBranchingPtr>::const_iterator bit=hardTree->branchings().begin();
bit!=hardTree->branchings().end();++bit) {
Energy2 dmin( 1e30*GeV2 );
ShowerProgenitorPtr partner;
for(vector<ShowerProgenitorPtr>::const_iterator pit=particlesToShower.begin();
pit!=particlesToShower.end();++pit) {
if(partners.find(*pit)!=partners.end()) continue;
if( (**bit).branchingParticle()->id() != (**pit).progenitor()->id() ) continue;
if( (**bit).branchingParticle()->isFinalState() !=
(**pit).progenitor()->isFinalState() ) continue;
if( (**pit).progenitor()->isFinalState() ) {
Energy2 dtest =
sqr( (**pit).progenitor()->momentum().x() - (**bit).showerMomentum().x() ) +
sqr( (**pit).progenitor()->momentum().y() - (**bit).showerMomentum().y() ) +
sqr( (**pit).progenitor()->momentum().z() - (**bit).showerMomentum().z() ) +
sqr( (**pit).progenitor()->momentum().t() - (**bit).showerMomentum().t() );
// add mass difference for identical particles (e.g. Z0 Z0 production)
dtest += 1e10*sqr((**pit).progenitor()->momentum().m()-(**bit).showerMomentum().m());
if( dtest < dmin ) {
partner = *pit;
dmin = dtest;
}
}
else {
// ensure directions are right
if((**pit).progenitor()->momentum().z()/(**bit).showerMomentum().z()>ZERO) {
partner = *pit;
break;
}
}
}
if(!partner) throw Exception() << "Failed to match shower and hard trees in QTildeShowerHandler::hardestEmission"
<< Exception::eventerror;
partners[partner] = *bit;
}
for(vector<ShowerProgenitorPtr>::const_iterator pit=particlesToShower.begin();
pit!=particlesToShower.end();++pit) {
HardBranchingPtr partner = partners[*pit];
if((**pit).progenitor()->dataPtr()->stable()) {
(**pit).progenitor()->set5Momentum(partner->showerMomentum());
(**pit).copy()->set5Momentum(partner->showerMomentum());
}
else {
Lorentz5Momentum oldMomentum = (**pit).progenitor()->momentum();
Lorentz5Momentum newMomentum = partner->showerMomentum();
LorentzRotation boost( oldMomentum.findBoostToCM(),oldMomentum.e()/oldMomentum.mass());
(**pit).progenitor()->transform(boost);
(**pit).copy() ->transform(boost);
boost = LorentzRotation(-newMomentum.findBoostToCM(),newMomentum.e()/newMomentum.mass());
(**pit).progenitor()->transform(boost);
(**pit).copy() ->transform(boost);
}
}
// correction boosts for daughter trees
for(map<tShowerTreePtr,pair<tShowerProgenitorPtr,tShowerParticlePtr> >::const_iterator
tit = showerTree->treelinks().begin();
tit != showerTree->treelinks().end();++tit) {
ShowerTreePtr decayTree = tit->first;
map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator
cit = decayTree->incomingLines().begin();
// reset the momentum of the decay particle
Lorentz5Momentum oldMomentum = cit->first->progenitor()->momentum();
Lorentz5Momentum newMomentum = tit->second.second->momentum();
LorentzRotation boost( oldMomentum.findBoostToCM(),oldMomentum.e()/oldMomentum.mass());
decayTree->transform(boost,true);
boost = LorentzRotation(-newMomentum.findBoostToCM(),newMomentum.e()/newMomentum.mass());
decayTree->transform(boost,true);
}
}
void QTildeShowerHandler::doShowering(bool hard,XCPtr xcomb) {
// zero number of emissions
_nis = _nfs = 0;
// if MC@NLO H event and limited emissions
// indicate both final and initial state emission
if ( currentTree()->isMCatNLOHEvent() && _limitEmissions != 0 ) {
_nis = _nfs = 1;
}
// extract particles to shower
vector<ShowerProgenitorPtr> particlesToShower(setupShower(hard));
// check if we should shower
bool colCharge = false;
for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
if(particlesToShower[ix]->progenitor()->dataPtr()->coloured() ||
particlesToShower[ix]->progenitor()->dataPtr()->charged()) {
colCharge = true;
break;
}
}
if(!colCharge) {
_currenttree->hasShowered(true);
return;
}
// setup the maximum scales for the shower
if (restrictPhasespace()) setupMaximumScales(particlesToShower,xcomb);
// set the hard scales for the profiles
setupHardScales(particlesToShower,xcomb);
// specific stuff for hard processes and decays
Energy minmass(ZERO), mIn(ZERO);
// hard process generate the intrinsic p_T once and for all
bool minBias = dynamic_ptr_cast<Ptr<MEMinBias>::ptr>(_hardme);
if(hard) {
_intrinsic.clear();
if(!minBias) generateIntrinsicpT(particlesToShower);
}
// decay compute the minimum mass of the final-state
else {
for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
if(particlesToShower[ix]->progenitor()->isFinalState()) {
if(particlesToShower[ix]->progenitor()->dataPtr()->stable()) {
auto dm= ShowerHandler::currentHandler()->retConstituentMasses()?
particlesToShower[ix]->progenitor()->dataPtr()->constituentMass():
particlesToShower[ix]->progenitor()->dataPtr()->mass();
minmass += dm;
}
else
minmass += particlesToShower[ix]->progenitor()->mass();
}
else {
mIn = particlesToShower[ix]->progenitor()->mass();
}
}
// throw exception if decay can't happen
if ( minmass > mIn ) {
throw Exception() << "QTildeShowerHandler.cc: Mass of decaying particle is "
<< "below constituent masses of decay products."
<< Exception::eventerror;
}
}
// setup for reweighted
bool reWeighting = _reWeight && hard && ShowerHandler::currentHandler()->firstInteraction();
double eventWeight=0.;
unsigned int nTryReWeight(0);
// create random particle vector (only need to do once)
vector<ShowerProgenitorPtr> tmp;
unsigned int nColouredIncoming = 0;
while(particlesToShower.size()>0){
unsigned int xx=UseRandom::irnd(particlesToShower.size());
tmp.push_back(particlesToShower[xx]);
particlesToShower.erase(particlesToShower.begin()+xx);
}
particlesToShower=tmp;
for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
if(!particlesToShower[ix]->progenitor()->isFinalState() &&
particlesToShower[ix]->progenitor()->coloured()) ++nColouredIncoming;
}
bool switchRecon = hard && nColouredIncoming !=1;
// main shower loop
unsigned int ntry(0);
bool reconstructed = false;
do {
// type of recon to use
bool generalRecon = minBias >> (switchRecon && ntry>maximumTries()/2);
// clear results of last attempt if needed
if(ntry!=0) {
currentTree()->clear();
setEvolutionPartners(hard,interaction_,true);
_nis = _nfs = 0;
// if MC@NLO H event and limited emissions
// indicate both final and initial state emission
if ( currentTree()->isMCatNLOHEvent() && _limitEmissions != 0 ) {
_nis = _nfs = 1;
}
for(unsigned int ix=0; ix<particlesToShower.size();++ix) {
SpinPtr spin = particlesToShower[ix]->progenitor()->spinInfo();
if(spin && spin->decayVertex() &&
dynamic_ptr_cast<tcSVertexPtr>(spin->decayVertex())) {
spin->decayVertex(VertexPtr());
}
}
for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
if(particlesToShower[ix]->progenitor()->isFinalState() ||
(hard && !particlesToShower[ix]->progenitor()->isFinalState())) {
if(particlesToShower[ix]->progenitor()->spinInfo())
particlesToShower[ix]->progenitor()->spinInfo()->reset();
}
}
}
// loop over particles
for(unsigned int ix=0;ix<particlesToShower.size();++ix) {
// extract the progenitor
progenitor(particlesToShower[ix]);
// final-state radiation
if(progenitor()->progenitor()->isFinalState()) {
if(!doFSR()) continue;
// perform shower
progenitor()->hasEmitted(startTimeLikeShower(interaction_));
}
// initial-state radiation
else {
if(!doISR()) continue;
// hard process
if(hard) {
// get the PDF
setBeamParticle(_progenitor->beam());
if(!beamParticle()) {
throw Exception() << "Incorrect type of beam particle in "
<< "QTildeShowerHandler::doShowering(). "
<< "This should not happen for conventional choices but may happen if you have used a"
<< " non-default choice and have not changed the create ParticleData line in the input files"
<< " for this particle to create BeamParticleData."
<< Exception::runerror;
}
// perform the shower
// set the beam particle
tPPtr beamparticle=progenitor()->original();
if(!beamparticle->parents().empty())
beamparticle=beamparticle->parents()[0];
// generate the shower
progenitor()->hasEmitted(startSpaceLikeShower(beamparticle,
interaction_));
}
// decay
else {
// skip colour and electrically neutral particles
if(!progenitor()->progenitor()->dataPtr()->coloured() &&
!progenitor()->progenitor()->dataPtr()->charged()) {
progenitor()->hasEmitted(false);
continue;
}
// perform shower
// set the scales correctly. The current scale is the maximum scale for
// emission not the starting scale
ShowerParticle::EvolutionScales maxScales(progenitor()->progenitor()->scales());
progenitor()->progenitor()->scales() = ShowerParticle::EvolutionScales();
if(progenitor()->progenitor()->dataPtr()->charged()) {
progenitor()->progenitor()->scales().QED = progenitor()->progenitor()->mass();
progenitor()->progenitor()->scales().QED_noAO = progenitor()->progenitor()->mass();
}
if(progenitor()->progenitor()->hasColour()) {
progenitor()->progenitor()->scales().QCD_c = progenitor()->progenitor()->mass();
progenitor()->progenitor()->scales().QCD_c_noAO = progenitor()->progenitor()->mass();
}
if(progenitor()->progenitor()->hasAntiColour()) {
progenitor()->progenitor()->scales().QCD_ac = progenitor()->progenitor()->mass();
progenitor()->progenitor()->scales().QCD_ac_noAO = progenitor()->progenitor()->mass();
}
// perform the shower
progenitor()->hasEmitted(startSpaceLikeDecayShower(maxScales,minmass,
interaction_));
}
}
}
// do the kinematic reconstruction, checking if it worked
reconstructed = hard ?
kinematicsReconstructor()->
reconstructHardJets (currentTree(),intrinsicpT(),interaction_,generalRecon) :
kinematicsReconstructor()->
reconstructDecayJets(currentTree(),interaction_);
if(!reconstructed) continue;
// apply vetos on the full shower
for(vector<FullShowerVetoPtr>::const_iterator it=_fullShowerVetoes.begin();
it!=_fullShowerVetoes.end();++it) {
int veto = (**it).applyVeto(currentTree());
if(veto<0) continue;
// veto the shower
if(veto==0) {
reconstructed = false;
break;
}
// veto the shower and reweight
else if(veto==1) {
reconstructed = false;
break;
}
// veto the event
else if(veto==2) {
throw Veto();
}
}
if(reWeighting) {
if(reconstructed) eventWeight += 1.;
reconstructed=false;
++nTryReWeight;
if(nTryReWeight==_nReWeight) {
reWeighting = false;
if(eventWeight==0.) throw Veto();
}
}
}
while(!reconstructed&&maximumTries()>++ntry);
// check if failed to generate the shower
if(ntry==maximumTries()) {
if(hard)
throw ShowerHandler::ShowerTriesVeto(ntry);
else
throw Exception() << "Failed to generate the shower after "
<< ntry << " attempts in QTildeShowerHandler::showerDecay()"
<< Exception::eventerror;
}
// handle the weights and apply any reweighting required
if(nTryReWeight>0) {
tStdEHPtr seh = dynamic_ptr_cast<tStdEHPtr>(generator()->currentEventHandler());
static bool first = true;
if(seh) {
seh->reweight(eventWeight/double(nTryReWeight));
}
else if(first) {
generator()->log() << "Reweighting the shower only works with internal Herwig7 processes"
<< "Presumably you are showering Les Houches Events. These will not be"
<< "reweighted\n";
first = false;
}
}
// tree has now showered
_currenttree->hasShowered(true);
hardTree(HardTreePtr());
}
void QTildeShowerHandler:: convertHardTree(bool hard,ShowerInteraction type) {
map<ColinePtr,ColinePtr> cmap;
// incoming particles
for(map<ShowerProgenitorPtr,ShowerParticlePtr>::const_iterator
cit=currentTree()->incomingLines().begin();cit!=currentTree()->incomingLines().end();++cit) {
map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator
mit = hardTree()->particles().find(cit->first->progenitor());
// put the colour lines in the map
ShowerParticlePtr oldParticle = cit->first->progenitor();
ShowerParticlePtr newParticle = mit->second->branchingParticle();
ColinePtr cLine = oldParticle-> colourLine();
ColinePtr aLine = oldParticle->antiColourLine();
if(newParticle->colourLine() &&
cmap.find(newParticle-> colourLine())==cmap.end())
cmap[newParticle-> colourLine()] = cLine;
if(newParticle->antiColourLine() &&
cmap.find(newParticle->antiColourLine())==cmap.end())
cmap[newParticle->antiColourLine()] = aLine;
// check whether or not particle emits
bool emission = mit->second->parent();
if(emission) {
if(newParticle->colourLine()) {
ColinePtr ctemp = newParticle-> colourLine();
ctemp->removeColoured(newParticle);
}
if(newParticle->antiColourLine()) {
ColinePtr ctemp = newParticle->antiColourLine();
ctemp->removeAntiColoured(newParticle);
}
newParticle = mit->second->parent()->branchingParticle();
}
// get the new colour lines
ColinePtr newCLine,newALine;
// sort out colour lines
if(newParticle->colourLine()) {
ColinePtr ctemp = newParticle-> colourLine();
ctemp->removeColoured(newParticle);
if(cmap.find(ctemp)!=cmap.end()) {
newCLine = cmap[ctemp];
}
else {
newCLine = new_ptr(ColourLine());
cmap[ctemp] = newCLine;
}
}
// and anticolour lines
if(newParticle->antiColourLine()) {
ColinePtr ctemp = newParticle->antiColourLine();
ctemp->removeAntiColoured(newParticle);
if(cmap.find(ctemp)!=cmap.end()) {
newALine = cmap[ctemp];
}
else {
newALine = new_ptr(ColourLine());
cmap[ctemp] = newALine;
}
}
// remove colour lines from old particle
if(aLine) {
aLine->removeAntiColoured(cit->first->copy());
aLine->removeAntiColoured(cit->first->progenitor());
}
if(cLine) {
cLine->removeColoured(cit->first->copy());
cLine->removeColoured(cit->first->progenitor());
}
// add particle to colour lines
if(newCLine) newCLine->addColoured (newParticle);
if(newALine) newALine->addAntiColoured(newParticle);
// insert new particles
cit->first->copy(newParticle);
ShowerParticlePtr sp(new_ptr(ShowerParticle(*newParticle,1,false)));
cit->first->progenitor(sp);
currentTree()->incomingLines()[cit->first]=sp;
cit->first->perturbative(!emission);
// and the emitted particle if needed
if(emission) {
ShowerParticlePtr newOut = mit->second->parent()->children()[1]->branchingParticle();
if(newOut->colourLine()) {
ColinePtr ctemp = newOut-> colourLine();
ctemp->removeColoured(newOut);
assert(cmap.find(ctemp)!=cmap.end());
cmap[ctemp]->addColoured (newOut);
}
if(newOut->antiColourLine()) {
ColinePtr ctemp = newOut->antiColourLine();
ctemp->removeAntiColoured(newOut);
assert(cmap.find(ctemp)!=cmap.end());
cmap[ctemp]->addAntiColoured(newOut);
}
ShowerParticlePtr sout=new_ptr(ShowerParticle(*newOut,1,true));
ShowerProgenitorPtr out=new_ptr(ShowerProgenitor(cit->first->original(),newOut,sout));
out->perturbative(false);
currentTree()->outgoingLines().insert(make_pair(out,sout));
}
if(hard) {
// sort out the value of x
if(mit->second->beam()->momentum().z()>ZERO) {
sp->x(newParticle->momentum(). plus()/mit->second->beam()->momentum(). plus());
}
else {
sp->x(newParticle->momentum().minus()/mit->second->beam()->momentum().minus());
}
}
}
// outgoing particles
for(map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
cit=currentTree()->outgoingLines().begin();cit!=currentTree()->outgoingLines().end();++cit) {
map<tShowerTreePtr,pair<tShowerProgenitorPtr,
tShowerParticlePtr> >::const_iterator tit;
for(tit = currentTree()->treelinks().begin();
tit != currentTree()->treelinks().end();++tit) {
if(tit->second.first && tit->second.second==cit->first->progenitor())
break;
}
map<ShowerParticlePtr,tHardBranchingPtr>::const_iterator
mit = hardTree()->particles().find(cit->first->progenitor());
if(mit==hardTree()->particles().end()) continue;
// put the colour lines in the map
ShowerParticlePtr oldParticle = cit->first->progenitor();
ShowerParticlePtr newParticle = mit->second->branchingParticle();
ShowerParticlePtr newOut;
ColinePtr cLine = oldParticle-> colourLine();
ColinePtr aLine = oldParticle->antiColourLine();
if(newParticle->colourLine() &&
cmap.find(newParticle-> colourLine())==cmap.end())
cmap[newParticle-> colourLine()] = cLine;
if(newParticle->antiColourLine() &&
cmap.find(newParticle->antiColourLine())==cmap.end())
cmap[newParticle->antiColourLine()] = aLine;
// check whether or not particle emits
bool emission = !mit->second->children().empty();
if(emission) {
if(newParticle->colourLine()) {
ColinePtr ctemp = newParticle-> colourLine();
ctemp->removeColoured(newParticle);
}
if(newParticle->antiColourLine()) {
ColinePtr ctemp = newParticle->antiColourLine();
ctemp->removeAntiColoured(newParticle);
}
newParticle = mit->second->children()[0]->branchingParticle();
newOut = mit->second->children()[1]->branchingParticle();
if(newParticle->id()!=oldParticle->id()&&newParticle->id()==newOut->id())
swap(newParticle,newOut);
}
// get the new colour lines
ColinePtr newCLine,newALine;
// sort out colour lines
if(newParticle->colourLine()) {
ColinePtr ctemp = newParticle-> colourLine();
ctemp->removeColoured(newParticle);
if(cmap.find(ctemp)!=cmap.end()) {
newCLine = cmap[ctemp];
}
else {
newCLine = new_ptr(ColourLine());
cmap[ctemp] = newCLine;
}
}
// and anticolour lines
if(newParticle->antiColourLine()) {
ColinePtr ctemp = newParticle->antiColourLine();
ctemp->removeAntiColoured(newParticle);
if(cmap.find(ctemp)!=cmap.end()) {
newALine = cmap[ctemp];
}
else {
newALine = new_ptr(ColourLine());
cmap[ctemp] = newALine;
}
}
// remove colour lines from old particle
if(aLine) {
aLine->removeAntiColoured(cit->first->copy());
aLine->removeAntiColoured(cit->first->progenitor());
}
if(cLine) {
cLine->removeColoured(cit->first->copy());
cLine->removeColoured(cit->first->progenitor());
}
// special for unstable particles
if(newParticle->id()==oldParticle->id() &&
(tit!=currentTree()->treelinks().end()||!oldParticle->dataPtr()->stable())) {
Lorentz5Momentum oldMomentum = oldParticle->momentum();
Lorentz5Momentum newMomentum = newParticle->momentum();
LorentzRotation boost( oldMomentum.findBoostToCM(),oldMomentum.e()/oldMomentum.mass());
if(tit!=currentTree()->treelinks().end()) tit->first->transform(boost,false);
oldParticle->transform(boost);
boost = LorentzRotation(-newMomentum.findBoostToCM(),newMomentum.e()/newMomentum.mass());
oldParticle->transform(boost);
if(tit!=currentTree()->treelinks().end()) tit->first->transform(boost,false);
newParticle=oldParticle;
}
// add particle to colour lines
if(newCLine) newCLine->addColoured (newParticle);
if(newALine) newALine->addAntiColoured(newParticle);
// insert new particles
cit->first->copy(newParticle);
ShowerParticlePtr sp(new_ptr(ShowerParticle(*newParticle,1,true)));
cit->first->progenitor(sp);
currentTree()->outgoingLines()[cit->first]=sp;
cit->first->perturbative(!emission);
// and the emitted particle if needed
if(emission) {
if(newOut->colourLine()) {
ColinePtr ctemp = newOut-> colourLine();
ctemp->removeColoured(newOut);
assert(cmap.find(ctemp)!=cmap.end());
cmap[ctemp]->addColoured (newOut);
}
if(newOut->antiColourLine()) {
ColinePtr ctemp = newOut->antiColourLine();
ctemp->removeAntiColoured(newOut);
assert(cmap.find(ctemp)!=cmap.end());
cmap[ctemp]->addAntiColoured(newOut);
}
ShowerParticlePtr sout=new_ptr(ShowerParticle(*newOut,1,true));
ShowerProgenitorPtr out=new_ptr(ShowerProgenitor(cit->first->original(),newOut,sout));
out->perturbative(false);
currentTree()->outgoingLines().insert(make_pair(out,sout));
}
// update any decay products
if(tit!=currentTree()->treelinks().end())
currentTree()->updateLink(tit->first,make_pair(cit->first,sp));
}
// reset the tree
currentTree()->resetShowerProducts();
// reextract the particles and set the colour partners
vector<ShowerParticlePtr> particles =
currentTree()->extractProgenitorParticles();
// clear the partners
for(unsigned int ix=0;ix<particles.size();++ix) {
particles[ix]->partner(ShowerParticlePtr());
particles[ix]->clearPartners();
}
// clear the tree
hardTree(HardTreePtr());
// Set the initial evolution scales
partnerFinder()->
setInitialEvolutionScales(particles,!hard,type,!_hardtree);
}
Branching QTildeShowerHandler::selectTimeLikeBranching(tShowerParticlePtr particle,
ShowerInteraction type,
HardBranchingPtr branch) {
Branching fb;
unsigned int iout=0;
while (true) {
// break if doing truncated shower and no truncated shower needed
if(branch && (!isTruncatedShowerON()||hardOnly())) break;
fb=_splittingGenerator->chooseForwardBranching(*particle,_finalenhance,type);
// no emission break
if(!fb.kinematics) break;
// special for truncated shower
if(branch) {
// check haven't evolved too far
if(fb.kinematics->scale() < branch->scale()) {
fb=Branching();
break;
}
// find the truncated line
iout=0;
if(fb.ids[1]->id()!=fb.ids[2]->id()) {
if(fb.ids[1]->id()==particle->id()) iout=1;
else if (fb.ids[2]->id()==particle->id()) iout=2;
}
else if(fb.ids[1]->id()==particle->id()) {
if(fb.kinematics->z()>0.5) iout=1;
else iout=2;
}
// apply the vetos for the truncated shower
// no flavour changing branchings
if(iout==0) {
particle->vetoEmission(fb.type,fb.kinematics->scale());
continue;
}
double zsplit = iout==1 ? fb.kinematics->z() : 1-fb.kinematics->z();
// only if same interaction for forced branching
ShowerInteraction type2 = convertInteraction(fb.type);
// and evolution
if(type2==branch->sudakov()->interactionType()) {
if(zsplit < 0.5 || // hardest line veto
fb.kinematics->scale()*zsplit < branch->scale() ) { // angular ordering veto
particle->vetoEmission(fb.type,fb.kinematics->scale());
continue;
}
}
// pt veto
if(fb.kinematics->pT() > progenitor()->maximumpT(type2)) {
particle->vetoEmission(fb.type,fb.kinematics->scale());
continue;
}
}
// standard vetos for all emissions
if(timeLikeVetoed(fb,particle)) {
particle->vetoEmission(fb.type,fb.kinematics->scale());
if(particle->spinInfo()) particle->spinInfo()->decayVertex(VertexPtr());
continue;
}
// special for already decayed particles
// don't allow flavour changing branchings
bool vetoDecay = false;
for(map<tShowerTreePtr,pair<tShowerProgenitorPtr,
tShowerParticlePtr> >::const_iterator tit = currentTree()->treelinks().begin();
tit != currentTree()->treelinks().end();++tit) {
if(tit->second.first == progenitor()) {
map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
it = currentTree()->outgoingLines().find(progenitor());
if(it!=currentTree()->outgoingLines().end() && particle == it->second &&
fb.ids[0]!=fb.ids[1] && fb.ids[1]!=fb.ids[2]) {
vetoDecay = true;
break;
}
}
}
if(vetoDecay) {
particle->vetoEmission(fb.type,fb.kinematics->scale());
if(particle->spinInfo()) particle->spinInfo()->decayVertex(VertexPtr());
continue;
}
break;
}
// normal case
if(!branch) {
if(fb.kinematics) fb.hard = false;
return fb;
}
// truncated emission
if(fb.kinematics) {
fb.hard = false;
fb.iout = iout;
return fb;
}
// otherwise need to return the hard emission
// construct the kinematics for the hard emission
ShoKinPtr showerKin = new_ptr(FS_QTildeShowerKinematics1to2(
branch->scale(),
branch->children()[0]->z(),
branch->phi(),
branch->children()[0]->pT(),
branch->sudakov()
));
IdList idlist(3);
idlist[0] = particle->dataPtr();
idlist[1] = branch->children()[0]->branchingParticle()->dataPtr();
idlist[2] = branch->children()[1]->branchingParticle()->dataPtr();
fb = Branching( showerKin, idlist, branch->sudakov(),branch->type() );
fb.hard = true;
fb.iout=0;
// return it
return fb;
}
Branching QTildeShowerHandler::selectSpaceLikeDecayBranching(tShowerParticlePtr particle,
const ShowerParticle::EvolutionScales & maxScales,
Energy minmass,ShowerInteraction type,
HardBranchingPtr branch) {
Branching fb;
unsigned int iout=0;
while (true) {
// break if doing truncated shower and no truncated shower needed
if(branch && (!isTruncatedShowerON()||hardOnly())) break;
// select branching
fb=_splittingGenerator->chooseDecayBranching(*particle,maxScales,minmass,
_initialenhance,type);
// return if no radiation
if(!fb.kinematics) break;
// special for truncated shower
if(branch) {
// check haven't evolved too far
if(fb.kinematics->scale() < branch->scale()) {
fb=Branching();
break;
}
// find the truncated line
iout=0;
if(fb.ids[1]->id()!=fb.ids[2]->id()) {
if(fb.ids[1]->id()==particle->id()) iout=1;
else if (fb.ids[2]->id()==particle->id()) iout=2;
}
else if(fb.ids[1]->id()==particle->id()) {
if(fb.kinematics->z()>0.5) iout=1;
else iout=2;
}
// apply the vetos for the truncated shower
// no flavour changing branchings
if(iout==0) {
particle->vetoEmission(fb.type,fb.kinematics->scale());
continue;
}
ShowerInteraction type2 = convertInteraction(fb.type);
double zsplit = iout==1 ? fb.kinematics->z() : 1-fb.kinematics->z();
if(type2==branch->sudakov()->interactionType()) {
if(zsplit < 0.5 || // hardest line veto
fb.kinematics->scale()*zsplit < branch->scale() ) { // angular ordering veto
particle->vetoEmission(fb.type,fb.kinematics->scale());
continue;
}
}
// pt veto
if(fb.kinematics->pT() > progenitor()->maximumpT(type2)) {
particle->vetoEmission(fb.type,fb.kinematics->scale());
continue;
}
}
// if not vetoed break
if(spaceLikeDecayVetoed(fb,particle)) {
// otherwise reset scale and continue
particle->vetoEmission(fb.type,fb.kinematics->scale());
continue;
}
break;
}
// normal case
if(!branch) {
if(fb.kinematics) fb.hard = false;
return fb;
}
// truncated emission
if(fb.kinematics) {
fb.hard = false;
fb.iout = iout;
return fb;
}
// otherwise need to return the hard emission
// construct the kinematics for the hard emission
ShoKinPtr showerKin = new_ptr(Decay_QTildeShowerKinematics1to2(
branch->scale(),
branch->children()[0]->z(),
branch->phi(),
branch->children()[0]->pT(),
branch->sudakov()));
IdList idlist(3);
idlist[0] = particle->dataPtr();
idlist[1] = branch->children()[0]->branchingParticle()->dataPtr();
idlist[2] = branch->children()[1]->branchingParticle()->dataPtr();
// create the branching
fb = Branching( showerKin, idlist, branch->sudakov(),ShowerPartnerType::QCDColourLine );
fb.hard=true;
fb.iout=0;
// return it
return fb;
}
void QTildeShowerHandler::checkFlags() {
string error = "Inconsistent hard emission set-up in QTildeShowerHandler::showerHardProcess(). ";
if ( ( currentTree()->isMCatNLOSEvent() || currentTree()->isMCatNLOHEvent() ) ) {
if (_hardEmission ==2 )
throw Exception() << error
<< "Cannot generate POWHEG matching with MC@NLO shower "
<< "approximation. Add 'set QTildeShowerHandler:HardEmission 0' to input file."
<< Exception::runerror;
if ( canHandleMatchboxTrunc() )
throw Exception() << error
<< "Cannot use truncated qtilde shower with MC@NLO shower "
<< "approximation. Set LHCGenerator:EventHandler"
<< ":CascadeHandler to '/Herwig/Shower/ShowerHandler' or "
<< "'/Herwig/Shower/Dipole/DipoleShowerHandler'."
<< Exception::runerror;
}
else if ( ((currentTree()->isPowhegSEvent() || currentTree()->isPowhegHEvent()) ) &&
_hardEmission != 2){
if ( canHandleMatchboxTrunc())
throw Exception() << error
<< "Unmatched events requested for POWHEG shower "
<< "approximation. Set QTildeShowerHandler:HardEmission to "
<< "'POWHEG'."
<< Exception::runerror;
else if (_hardEmissionWarn) {
_hardEmissionWarn = false;
_hardEmission=2;
throw Exception() << error
<< "Unmatched events requested for POWHEG shower "
<< "approximation. Changing QTildeShowerHandler:HardEmission from "
<< _hardEmission << " to 2"
<< Exception::warning;
}
}
if ( currentTree()->isPowhegSEvent() || currentTree()->isPowhegHEvent()) {
if (currentTree()->showerApproximation()->needsTruncatedShower() &&
!canHandleMatchboxTrunc() )
throw Exception() << error
<< "Current shower handler cannot generate truncated shower. "
<< "Set Generator:EventHandler:CascadeHandler to "
<< "'/Herwig/Shower/PowhegShowerHandler'."
<< Exception::runerror;
}
else if ( currentTree()->truncatedShower() && _missingTruncWarn) {
_missingTruncWarn=false;
throw Exception() << "Warning: POWHEG shower approximation used without "
<< "truncated shower. Set Generator:EventHandler:"
<< "CascadeHandler to '/Herwig/Shower/PowhegShowerHandler' and "
<< "'MEMatching:TruncatedShower Yes'."
<< Exception::warning;
}
// else if ( !dipme && _hardEmissionMode > 1 &&
// firstInteraction())
// throw Exception() << error
// << "POWHEG matching requested for LO events. Include "
// << "'set Factory:ShowerApproximation MEMatching' in input file."
// << Exception::runerror;
}
tPPair QTildeShowerHandler::remakeRemnant(tPPair oldp){
// get the parton extractor
PartonExtractor & pex = *lastExtractor();
// get the new partons
tPPair newp = make_pair(findFirstParton(oldp.first ),
findFirstParton(oldp.second));
// if the same do nothing
if(newp == oldp) return oldp;
// Creates the new remnants and returns the new PartonBinInstances
// ATTENTION Broken here for very strange configuration
PBIPair newbins = pex.newRemnants(oldp, newp, newStep());
newStep()->addIntermediate(newp.first);
newStep()->addIntermediate(newp.second);
// return the new partons
return newp;
}
PPtr QTildeShowerHandler::findFirstParton(tPPtr seed) const{
if(seed->parents().empty()) return seed;
tPPtr parent = seed->parents()[0];
//if no parent there this is a loose end which will
//be connected to the remnant soon.
if(!parent || parent == incomingBeams().first ||
parent == incomingBeams().second ) return seed;
else return findFirstParton(parent);
}
void QTildeShowerHandler::decay(ShowerTreePtr tree, ShowerDecayMap & decay) {
// must be one incoming particle
assert(tree->incomingLines().size()==1);
// apply any transforms
tree->applyTransforms();
// if already decayed return
if(!tree->outgoingLines().empty()) return;
// now we need to replace the particle with a new copy after the shower
// find particle after the shower
map<tShowerTreePtr,pair<tShowerProgenitorPtr,tShowerParticlePtr> >::const_iterator
tit = tree->parent()->treelinks().find(tree);
assert(tit!=tree->parent()->treelinks().end());
ShowerParticlePtr newparent=tit->second.second;
PerturbativeProcessPtr newProcess = new_ptr(PerturbativeProcess());
newProcess->incoming().push_back(make_pair(newparent,PerturbativeProcessPtr()));
DecayProcessMap decayMap;
ShowerHandler::decay(newProcess,decayMap);
ShowerTree::constructTrees(tree,decay,newProcess,decayMap);
}
namespace {
ShowerProgenitorPtr
findFinalStateLine(ShowerTreePtr tree, long id, Lorentz5Momentum momentum) {
map<ShowerProgenitorPtr,tShowerParticlePtr>::iterator partner;
Energy2 dmin(1e30*GeV2);
for(map<ShowerProgenitorPtr,tShowerParticlePtr>::iterator
cit =tree->outgoingLines().begin(); cit!=tree->outgoingLines().end(); ++cit) {
if(cit->second->id()!=id) continue;
Energy2 test =
sqr(cit->second->momentum().x()-momentum.x())+
sqr(cit->second->momentum().y()-momentum.y())+
sqr(cit->second->momentum().z()-momentum.z())+
sqr(cit->second->momentum().t()-momentum.t());
if(test<dmin) {
dmin = test;
partner = cit;
}
}
return partner->first;
}
ShowerProgenitorPtr
findInitialStateLine(ShowerTreePtr tree, long id, Lorentz5Momentum momentum) {
map<ShowerProgenitorPtr,ShowerParticlePtr>::iterator partner;
Energy2 dmin(1e30*GeV2);
for(map<ShowerProgenitorPtr,ShowerParticlePtr>::iterator
cit =tree->incomingLines().begin(); cit!=tree->incomingLines().end(); ++cit) {
if(cit->second->id()!=id) continue;
Energy2 test =
sqr(cit->second->momentum().x()-momentum.x())+
sqr(cit->second->momentum().y()-momentum.y())+
sqr(cit->second->momentum().z()-momentum.z())+
sqr(cit->second->momentum().t()-momentum.t());
if(test<dmin) {
dmin = test;
partner = cit;
}
}
return partner->first;
}
void fixSpectatorColours(PPtr newSpect,ShowerProgenitorPtr oldSpect,
ColinePair & cline,ColinePair & aline, bool reconnect) {
cline.first = oldSpect->progenitor()->colourLine();
cline.second = newSpect->colourLine();
aline.first = oldSpect->progenitor()->antiColourLine();
aline.second = newSpect->antiColourLine();
if(!reconnect) return;
if(cline.first) {
cline.first ->removeColoured(oldSpect->copy());
cline.first ->removeColoured(oldSpect->progenitor());
cline.second->removeColoured(newSpect);
cline.first ->addColoured(newSpect);
}
if(aline.first) {
aline.first ->removeAntiColoured(oldSpect->copy());
aline.first ->removeAntiColoured(oldSpect->progenitor());
aline.second->removeAntiColoured(newSpect);
aline.first ->addAntiColoured(newSpect);
}
}
void fixInitialStateEmitter(ShowerTreePtr tree, PPtr newEmit,PPtr emitted, ShowerProgenitorPtr emitter,
ColinePair cline,ColinePair aline,double x) {
// sort out the colours
if(emitted->dataPtr()->iColour()==PDT::Colour8) {
// emitter
if(cline.first && cline.first == emitter->progenitor()->antiColourLine() &&
cline.second !=newEmit->antiColourLine()) {
// sort out not radiating line
ColinePtr col = emitter->progenitor()->colourLine();
if(col) {
col->removeColoured(emitter->copy());
col->removeColoured(emitter->progenitor());
newEmit->colourLine()->removeColoured(newEmit);
col->addColoured(newEmit);
}
}
else if(aline.first && aline.first == emitter->progenitor()->colourLine() &&
aline.second !=newEmit->colourLine()) {
// sort out not radiating line
ColinePtr anti = emitter->progenitor()->antiColourLine();
if(anti) {
anti->removeAntiColoured(emitter->copy());
anti->removeAntiColoured(emitter->progenitor());
newEmit->colourLine()->removeAntiColoured(newEmit);
anti->addAntiColoured(newEmit);
}
}
else
assert(false);
// emitted
if(cline.first && cline.second==emitted->colourLine()) {
cline.second->removeColoured(emitted);
cline.first->addColoured(emitted);
}
else if(aline.first && aline.second==emitted->antiColourLine()) {
aline.second->removeAntiColoured(emitted);
aline.first->addAntiColoured(emitted);
}
else
assert(false);
}
else {
if(emitter->progenitor()->antiColourLine() ) {
ColinePtr col = emitter->progenitor()->antiColourLine();
col->removeAntiColoured(emitter->copy());
col->removeAntiColoured(emitter->progenitor());
if(newEmit->antiColourLine()) {
newEmit->antiColourLine()->removeAntiColoured(newEmit);
col->addAntiColoured(newEmit);
}
else if (emitted->colourLine()) {
emitted->colourLine()->removeColoured(emitted);
col->addColoured(emitted);
}
else
assert(false);
}
if(emitter->progenitor()->colourLine() ) {
ColinePtr col = emitter->progenitor()->colourLine();
col->removeColoured(emitter->copy());
col->removeColoured(emitter->progenitor());
if(newEmit->colourLine()) {
newEmit->colourLine()->removeColoured(newEmit);
col->addColoured(newEmit);
}
else if (emitted->antiColourLine()) {
emitted->antiColourLine()->removeAntiColoured(emitted);
col->addAntiColoured(emitted);
}
else
assert(false);
}
}
// update the emitter
emitter->copy(newEmit);
ShowerParticlePtr sp = new_ptr(ShowerParticle(*newEmit,1,false));
sp->x(x);
emitter->progenitor(sp);
tree->incomingLines()[emitter]=sp;
emitter->perturbative(false);
// add emitted
sp=new_ptr(ShowerParticle(*emitted,1,true));
ShowerProgenitorPtr gluon=new_ptr(ShowerProgenitor(emitter->original(),emitted,sp));
gluon->perturbative(false);
tree->outgoingLines().insert(make_pair(gluon,sp));
}
void fixFinalStateEmitter(ShowerTreePtr tree, PPtr newEmit,PPtr emitted, ShowerProgenitorPtr emitter,
ColinePair cline,ColinePair aline) {
map<tShowerTreePtr,pair<tShowerProgenitorPtr,tShowerParticlePtr> >::const_iterator tit;
// special case if decayed
for(tit = tree->treelinks().begin(); tit != tree->treelinks().end();++tit) {
if(tit->second.first && tit->second.second==emitter->progenitor())
break;
}
// sort out the colour lines
if(cline.first && cline.first == emitter->progenitor()->antiColourLine() &&
cline.second !=newEmit->antiColourLine()) {
// sort out not radiating line
ColinePtr col = emitter->progenitor()->colourLine();
if(col) {
col->removeColoured(emitter->copy());
col->removeColoured(emitter->progenitor());
newEmit->colourLine()->removeColoured(newEmit);
col->addColoured(newEmit);
}
}
else if(aline.first && aline.first == emitter->progenitor()->colourLine() &&
aline.second !=newEmit->colourLine()) {
// sort out not radiating line
ColinePtr anti = emitter->progenitor()->antiColourLine();
if(anti) {
anti->removeAntiColoured(emitter->copy());
anti->removeAntiColoured(emitter->progenitor());
newEmit->colourLine()->removeAntiColoured(newEmit);
anti->addAntiColoured(newEmit);
}
}
else
assert(false);
// update the emitter
emitter->copy(newEmit);
ShowerParticlePtr sp = new_ptr(ShowerParticle(*newEmit,1,true));
emitter->progenitor(sp);
tree->outgoingLines()[emitter]=sp;
emitter->perturbative(false);
// update for decaying particles
if(tit!=tree->treelinks().end())
tree->updateLink(tit->first,make_pair(emitter,sp));
// add the emitted particle
// sort out the colour
if(cline.first && cline.second==emitted->antiColourLine()) {
cline.second->removeAntiColoured(emitted);
cline.first->addAntiColoured(emitted);
}
else if(aline.first && aline.second==emitted->colourLine()) {
aline.second->removeColoured(emitted);
aline.first->addColoured(emitted);
}
else
assert(false);
sp=new_ptr(ShowerParticle(*emitted,1,true));
ShowerProgenitorPtr gluon=new_ptr(ShowerProgenitor(emitter->original(),
emitted,sp));
gluon->perturbative(false);
tree->outgoingLines().insert(make_pair(gluon,sp));
}
}
void QTildeShowerHandler::setupMECorrection(RealEmissionProcessPtr real) {
assert(real);
// II emission
if(real->emitter() < real->incoming().size() &&
real->spectator() < real->incoming().size()) {
// recoiling system
for( map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
cjt= currentTree()->outgoingLines().begin();
cjt != currentTree()->outgoingLines().end();++cjt ) {
cjt->first->progenitor()->transform(real->transformation());
cjt->first->copy()->transform(real->transformation());
}
// the the radiating system
ShowerProgenitorPtr emitter,spectator;
unsigned int iemit = real->emitter();
unsigned int ispect = real->spectator();
int ig = int(real->emitted())-int(real->incoming().size());
emitter = findInitialStateLine(currentTree(),
real->bornIncoming()[iemit]->id(),
real->bornIncoming()[iemit]->momentum());
spectator = findInitialStateLine(currentTree(),
real->bornIncoming()[ispect]->id(),
real->bornIncoming()[ispect]->momentum());
// sort out the colours
ColinePair cline,aline;
fixSpectatorColours(real->incoming()[ispect],spectator,cline,aline,true);
// update the spectator
spectator->copy(real->incoming()[ispect]);
ShowerParticlePtr sp(new_ptr(ShowerParticle(*real->incoming()[ispect],1,false)));
sp->x(ispect ==0 ? real->x().first :real->x().second);
spectator->progenitor(sp);
currentTree()->incomingLines()[spectator]=sp;
spectator->perturbative(true);
// now for the emitter
fixInitialStateEmitter(currentTree(),real->incoming()[iemit],real->outgoing()[ig],
emitter,cline,aline,iemit ==0 ? real->x().first :real->x().second);
}
// FF emission
else if(real->emitter() >= real->incoming().size() &&
real->spectator() >= real->incoming().size()) {
assert(real->outgoing()[real->emitted()-real->incoming().size()]->id()==ParticleID::g);
// find the emitter and spectator in the shower tree
ShowerProgenitorPtr emitter,spectator;
int iemit = int(real->emitter())-int(real->incoming().size());
emitter = findFinalStateLine(currentTree(),
real->bornOutgoing()[iemit]->id(),
real->bornOutgoing()[iemit]->momentum());
int ispect = int(real->spectator())-int(real->incoming().size());
spectator = findFinalStateLine(currentTree(),
real->bornOutgoing()[ispect]->id(),
real->bornOutgoing()[ispect]->momentum());
map<tShowerTreePtr,pair<tShowerProgenitorPtr,tShowerParticlePtr> >::const_iterator tit;
// first the spectator
// special case if decayed
for(tit = currentTree()->treelinks().begin(); tit != currentTree()->treelinks().end();++tit) {
if(tit->second.first && tit->second.second==spectator->progenitor())
break;
}
// sort out the colours
ColinePair cline,aline;
fixSpectatorColours(real->outgoing()[ispect],spectator,cline,aline,true);
// update the spectator
spectator->copy(real->outgoing()[ispect]);
ShowerParticlePtr sp(new_ptr(ShowerParticle(*real->outgoing()[ispect],1,true)));
spectator->progenitor(sp);
currentTree()->outgoingLines()[spectator]=sp;
spectator->perturbative(true);
// update for decaying particles
if(tit!=currentTree()->treelinks().end())
currentTree()->updateLink(tit->first,make_pair(spectator,sp));
// now the emitting particle
int ig = int(real->emitted())-int(real->incoming().size());
fixFinalStateEmitter(currentTree(),real->outgoing()[iemit],
real->outgoing()[ig],
emitter,cline,aline);
}
// IF emission
else {
// scattering process
if(real->incoming().size()==2) {
ShowerProgenitorPtr emitter,spectator;
unsigned int iemit = real->emitter();
unsigned int ispect = real->spectator();
int ig = int(real->emitted())-int(real->incoming().size());
ColinePair cline,aline;
// incoming spectator
if(ispect<2) {
spectator = findInitialStateLine(currentTree(),
real->bornIncoming()[ispect]->id(),
real->bornIncoming()[ispect]->momentum());
fixSpectatorColours(real->incoming()[ispect],spectator,cline,aline,true);
// update the spectator
spectator->copy(real->incoming()[ispect]);
ShowerParticlePtr sp(new_ptr(ShowerParticle(*real->incoming()[ispect],1,false)));
sp->x(ispect ==0 ? real->x().first :real->x().second);
spectator->progenitor(sp);
currentTree()->incomingLines()[spectator]=sp;
spectator->perturbative(true);
}
// outgoing spectator
else {
spectator = findFinalStateLine(currentTree(),
real->bornOutgoing()[ispect-real->incoming().size()]->id(),
real->bornOutgoing()[ispect-real->incoming().size()]->momentum());
// special case if decayed
map<tShowerTreePtr,pair<tShowerProgenitorPtr,tShowerParticlePtr> >::const_iterator tit;
for(tit = currentTree()->treelinks().begin(); tit != currentTree()->treelinks().end();++tit) {
if(tit->second.first && tit->second.second==spectator->progenitor())
break;
}
fixSpectatorColours(real->outgoing()[ispect-real->incoming().size()],spectator,cline,aline,true);
// update the spectator
spectator->copy(real->outgoing()[ispect-real->incoming().size()]);
ShowerParticlePtr sp(new_ptr(ShowerParticle(*real->outgoing()[ispect-real->incoming().size()],1,true)));
spectator->progenitor(sp);
currentTree()->outgoingLines()[spectator]=sp;
spectator->perturbative(true);
// update for decaying particles
if(tit!=currentTree()->treelinks().end())
currentTree()->updateLink(tit->first,make_pair(spectator,sp));
}
// incoming emitter
if(iemit<2) {
emitter = findInitialStateLine(currentTree(),
real->bornIncoming()[iemit]->id(),
real->bornIncoming()[iemit]->momentum());
fixInitialStateEmitter(currentTree(),real->incoming()[iemit],real->outgoing()[ig],
emitter,aline,cline,iemit ==0 ? real->x().first :real->x().second);
}
// outgoing emitter
else {
emitter = findFinalStateLine(currentTree(),
real->bornOutgoing()[iemit-real->incoming().size()]->id(),
real->bornOutgoing()[iemit-real->incoming().size()]->momentum());
fixFinalStateEmitter(currentTree(),real->outgoing()[iemit-real->incoming().size()],
real->outgoing()[ig],emitter,aline,cline);
}
}
// decay process
else {
assert(real->spectator()==0);
unsigned int iemit = real->emitter()-real->incoming().size();
int ig = int(real->emitted())-int(real->incoming().size());
ColinePair cline,aline;
// incoming spectator
ShowerProgenitorPtr spectator = findInitialStateLine(currentTree(),
real->bornIncoming()[0]->id(),
real->bornIncoming()[0]->momentum());
fixSpectatorColours(real->incoming()[0],spectator,cline,aline,false);
// find the emitter
ShowerProgenitorPtr emitter =
findFinalStateLine(currentTree(),
real->bornOutgoing()[iemit]->id(),
real->bornOutgoing()[iemit]->momentum());
// recoiling system
for( map<ShowerProgenitorPtr,tShowerParticlePtr>::const_iterator
cjt= currentTree()->outgoingLines().begin();
cjt != currentTree()->outgoingLines().end();++cjt ) {
if(cjt->first==emitter) continue;
cjt->first->progenitor()->transform(real->transformation());
cjt->first->copy()->transform(real->transformation());
}
// sort out the emitter
fixFinalStateEmitter(currentTree(),real->outgoing()[iemit],
real->outgoing()[ig],emitter,aline,cline);
}
}
// clean up the shower tree
_currenttree->resetShowerProducts();
}
diff --git a/Shower/QTilde/QTildeShowerHandler.h b/Shower/QTilde/QTildeShowerHandler.h
--- a/Shower/QTilde/QTildeShowerHandler.h
+++ b/Shower/QTilde/QTildeShowerHandler.h
@@ -1,841 +1,833 @@
// -*- C++ -*-
#ifndef Herwig_QTildeShowerHandler_H
#define Herwig_QTildeShowerHandler_H
//
// This is the declaration of the QTildeShowerHandler class.
//
#include "QTildeShowerHandler.fh"
#include "Herwig/Shower/ShowerHandler.h"
#include "Herwig/Shower/QTilde/SplittingFunctions/SplittingGenerator.h"
#include "Herwig/Shower/QTilde/Base/ShowerTree.h"
#include "Herwig/Shower/QTilde/Base/ShowerProgenitor.fh"
#include "Herwig/Shower/QTilde/Base/HardTree.h"
#include "Herwig/Shower/QTilde/Base/Branching.h"
#include "Herwig/Shower/QTilde/Base/ShowerVeto.h"
#include "Herwig/Shower/QTilde/Base/FullShowerVeto.h"
#include "Herwig/Shower/QTilde/Kinematics/KinematicsReconstructor.fh"
#include "Herwig/Shower/QTilde/Base/PartnerFinder.fh"
#include "Herwig/Shower/QTilde/SplittingFunctions/SudakovFormFactor.fh"
#include "Herwig/MatrixElement/HwMEBase.h"
#include "Herwig/Decay/HwDecayerBase.h"
#include "Herwig/MatrixElement/Matchbox/Matching/ShowerApproximation.h"
#include "Herwig/Shower/RealEmissionProcess.h"
#include "Herwig/Utilities/Statistic.h"
namespace Herwig {
using namespace ThePEG;
/**
* The QTildeShowerHandler class.
*
* @see \ref QTildeShowerHandlerInterfaces "The interfaces"
* defined for QTildeShowerHandler.
*/
class QTildeShowerHandler: public ShowerHandler {
public:
/**
* Pointer to an XComb object
*/
typedef Ptr<XComb>::pointer XCPtr;
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
QTildeShowerHandler();
- /**
- * The destructor.
- */
- virtual ~QTildeShowerHandler();
- //@}
-
public:
/**
* At the end of the Showering, transform ShowerParticle objects
* into ThePEG particles and fill the event record with them.
* Notice that the parent/child relationships and the
* transformation from ShowerColourLine objects into ThePEG
* ColourLine ones must be properly handled.
*/
void fillEventRecord();
/**
* Return the relevant hard scale to be used in the profile scales
*/
virtual Energy hardScale() const {
return muPt;
}
/**
* Hook to allow vetoing of event after showering hard sub-process
* as in e.g. MLM merging.
*/
virtual bool showerHardProcessVeto() const { return false; }
/**
* Generate hard emissions for CKKW etc
*/
virtual HardTreePtr generateCKKW(ShowerTreePtr tree) const;
/**
* Members to perform the shower
*/
//@{
/**
* Perform the shower of the hard process
*/
virtual void showerHardProcess(ShowerTreePtr,XCPtr);
/**
* Perform the shower of a decay
*/
virtual void showerDecay(ShowerTreePtr);
//@}
/**
* Access to the flags and shower variables
*/
//@{
/**
* Get the SplittingGenerator
*/
tSplittingGeneratorPtr splittingGenerator() const { return _splittingGenerator; }
/**
* Mode for hard emissions
*/
int hardEmission() const {return _hardEmission;}
//@}
/**
* Connect the Hard and Shower trees
*/
virtual void connectTrees(ShowerTreePtr showerTree, HardTreePtr hardTree, bool hard );
/**
* Access to switches for spin correlations
*/
//@{
/**
* Soft correlations
*/
unsigned int softCorrelations() const {
return _softOpt;
}
/**
* Any correlations
*/
virtual bool correlations() const {
return spinCorrelations()!=0||_softOpt!=0;
}
//@}
public:
/**
* Access methods to access the objects
*/
//@{
/**
* Access to the KinematicsReconstructor object
*/
tKinematicsReconstructorPtr kinematicsReconstructor() const { return _reconstructor; }
/**
* Access to the PartnerFinder object
*/
tPartnerFinderPtr partnerFinder() const { return _partnerfinder; }
//@}
protected:
/**
* Perform the shower
*/
void doShowering(bool hard,XCPtr);
/**
* Generate the hard matrix element correction
*/
virtual RealEmissionProcessPtr hardMatrixElementCorrection(bool);
/**
* Generate the hardest emission
*/
virtual void hardestEmission(bool hard);
/**
* Set up for applying a matrix element correction
*/
void setupMECorrection(RealEmissionProcessPtr real);
/**
* Extract the particles to be showered, set the evolution scales
* and apply the hard matrix element correction
* @param hard Whether this is a hard process or decay
* @return The particles to be showered
*/
virtual vector<ShowerProgenitorPtr> setupShower(bool hard);
/**
* set the colour partners
*/
virtual void setEvolutionPartners(bool hard,ShowerInteraction,
bool clear);
/**
* Methods to perform the evolution of an individual particle, including
* recursive calling on the products
*/
//@{
/**
* It does the forward evolution of the time-like input particle
* (and recursively for all its radiation products).
* accepting only emissions which conforms to the showerVariables
* and soft matrix element correction.
* If at least one emission has occurred then the method returns true.
* @param particle The particle to be showered
*/
virtual bool timeLikeShower(tShowerParticlePtr particle, ShowerInteraction,
Branching fb, bool first);
/**
* It does the backward evolution of the space-like input particle
* (and recursively for all its time-like radiation products).
* accepting only emissions which conforms to the showerVariables.
* If at least one emission has occurred then the method returns true
* @param particle The particle to be showered
* @param beam The beam particle
*/
virtual bool spaceLikeShower(tShowerParticlePtr particle,PPtr beam,
ShowerInteraction);
/**
* If does the forward evolution of the input on-shell particle
* involved in a decay
* (and recursively for all its time-like radiation products).
* accepting only emissions which conforms to the showerVariables.
* @param particle The particle to be showered
* @param maxscale The maximum scale for the shower.
* @param minimumMass The minimum mass of the final-state system
*/
virtual bool
spaceLikeDecayShower(tShowerParticlePtr particle,
const ShowerParticle::EvolutionScales & maxScales,
Energy minimumMass,ShowerInteraction,
Branching fb);
/**
* Truncated shower from a time-like particle
*/
virtual bool truncatedTimeLikeShower(tShowerParticlePtr particle,
HardBranchingPtr branch,
ShowerInteraction type,
Branching fb, bool first);
/**
* Truncated shower from a space-like particle
*/
virtual bool truncatedSpaceLikeShower(tShowerParticlePtr particle,PPtr beam,
HardBranchingPtr branch,
ShowerInteraction type);
/**
* Truncated shower from a time-like particle
*/
virtual bool truncatedSpaceLikeDecayShower(tShowerParticlePtr particle,
const ShowerParticle::EvolutionScales & maxScales,
Energy minimumMass, HardBranchingPtr branch,
ShowerInteraction type, Branching fb);
//@}
/**
* Switches for matrix element corrections
*/
//@{
/**
* Any ME correction?
*/
bool MECOn() const {
return _hardEmission == 1;
}
/**
* Any hard ME correction?
*/
bool hardMEC() const {
return _hardEmission == 1 && (_meCorrMode == 1 || _meCorrMode == 2);
}
/**
* Any soft ME correction?
*/
bool softMEC() const {
return _hardEmission == 1 && (_meCorrMode == 1 || _meCorrMode > 2);
}
//@}
/**
* Is the truncated shower on?
*/
bool isTruncatedShowerON() const {return _trunc_Mode;}
/**
* Switch for intrinsic pT
*/
//@{
/**
* Any intrinsic pT?
*/
bool ipTon() const {
return _iptrms != ZERO || ( _beta == 1.0 && _gamma != ZERO && _iptmax !=ZERO );
}
//@}
/**@name Additional shower vetoes */
//@{
/**
* Insert a veto.
*/
void addVeto (ShowerVetoPtr v) { _vetoes.push_back(v); }
/**
* Remove a veto.
*/
void removeVeto (ShowerVetoPtr v) {
vector<ShowerVetoPtr>::iterator vit = find(_vetoes.begin(),_vetoes.end(),v);
if (vit != _vetoes.end())
_vetoes.erase(vit);
}
//@}
/**
* Switches for vetoing hard emissions
*/
//@{
/**
* Returns true if the hard veto read-in is to be applied to only
* the primary collision and false otherwise.
*/
bool hardVetoReadOption() const {return _hardVetoReadOption;}
//@}
/**
* Enhancement factors for radiation needed to generate the soft matrix
* element correction.
*/
//@{
/**
* Access the enhancement factor for initial-state radiation
*/
double initialStateRadiationEnhancementFactor() const { return _initialenhance; }
/**
* Access the enhancement factor for final-state radiation
*/
double finalStateRadiationEnhancementFactor() const { return _finalenhance; }
/**
* Set the enhancement factor for initial-state radiation
*/
void initialStateRadiationEnhancementFactor(double in) { _initialenhance=in; }
/**
* Set the enhancement factor for final-state radiation
*/
void finalStateRadiationEnhancementFactor(double in) { _finalenhance=in; }
//@}
/**
* Access to set/get the HardTree currently beinging showered
*/
//@{
/**
* The HardTree currently being showered
*/
tHardTreePtr hardTree() {return _hardtree;}
/**
* The HardTree currently being showered
*/
void hardTree(tHardTreePtr in) {_hardtree = in;}
//@}
/**
* Access/set the beam particle for the current initial-state shower
*/
//@{
/**
* Get the beam particle data
*/
Ptr<BeamParticleData>::const_pointer beamParticle() const { return _beam; }
/**
* Set the beam particle data
*/
void setBeamParticle(Ptr<BeamParticleData>::const_pointer in) { _beam=in; }
//@}
/**
* Set/Get the current tree being evolver for inheriting classes
*/
//@{
/**
* Get the tree
*/
tShowerTreePtr currentTree() { return _currenttree; }
/**
* Set the tree
*/
void currentTree(tShowerTreePtr tree) { _currenttree=tree; }
//@}
/**
* Access the maximum number of attempts to generate the shower
*/
unsigned int maximumTries() const { return _maxtry; }
/**
* Set/Get the ShowerProgenitor for the current shower
*/
//@{
/**
* Access the progenitor
*/
ShowerProgenitorPtr progenitor() { return _progenitor; }
/**
* Set the progenitor
*/
void progenitor(ShowerProgenitorPtr in) { _progenitor=in; }
//@}
/**
* Calculate the intrinsic \f$p_T\f$.
*/
virtual void generateIntrinsicpT(vector<ShowerProgenitorPtr>);
/**
* Access to the intrinsic \f$p_T\f$ for inheriting classes
*/
map<tShowerProgenitorPtr,pair<Energy,double> > & intrinsicpT() { return _intrinsic; }
/**
* find the maximally allowed pt acc to the hard process.
*/
void setupMaximumScales(const vector<ShowerProgenitorPtr> &,XCPtr);
/**
* find the relevant hard scales for profile scales.
*/
void setupHardScales(const vector<ShowerProgenitorPtr> &,XCPtr);
/**
* Convert the HardTree into an extra shower emission
*/
void convertHardTree(bool hard,ShowerInteraction type);
protected:
/**
* Find the parton extracted from the incoming particle after ISR
*/
PPtr findFirstParton(tPPtr seed) const;
/**
* Fix Remnant connections after ISR
*/
tPPair remakeRemnant(tPPair oldp);
protected:
/**
* Start the shower of a timelike particle
*/
virtual bool startTimeLikeShower(ShowerInteraction);
/**
* Update of the time-like stuff
*/
void updateHistory(tShowerParticlePtr particle);
/**
* Start the shower of a spacelike particle
*/
virtual bool startSpaceLikeShower(PPtr,ShowerInteraction);
/**
* Start the shower of a spacelike particle
*/
virtual bool
startSpaceLikeDecayShower(const ShowerParticle::EvolutionScales & maxScales,
Energy minimumMass,ShowerInteraction);
/**
* Select the branching for the next time-like emission
*/
Branching selectTimeLikeBranching(tShowerParticlePtr particle,
ShowerInteraction type,
HardBranchingPtr branch);
/**
* Select the branching for the next space-like emission in a decay
*/
Branching selectSpaceLikeDecayBranching(tShowerParticlePtr particle,
const ShowerParticle::EvolutionScales & maxScales,
Energy minmass,ShowerInteraction type,
HardBranchingPtr branch);
/**
* Create the timelike child of a branching
*/
ShowerParticleVector createTimeLikeChildren(tShowerParticlePtr particle,
IdList ids);
/**
* Vetos for the timelike shower
*/
virtual bool timeLikeVetoed(const Branching &,ShowerParticlePtr);
/**
* Vetos for the spacelike shower
*/
virtual bool spaceLikeVetoed(const Branching &,ShowerParticlePtr);
/**
* Vetos for the spacelike shower
*/
virtual bool spaceLikeDecayVetoed(const Branching &,ShowerParticlePtr);
/**
* Only generate the hard emission, for testing only.
*/
bool hardOnly() const {return _limitEmissions==3;}
/**
* Check the flags
*/
void checkFlags();
/**
*
*/
void addFSRUsingDecayPOWHEG(HardTreePtr ISRTree);
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:
/**
* The main method which manages the showering of a subprocess.
*/
virtual tPPair cascade(tSubProPtr sub, XCPtr xcomb);
/**
* Decay a ShowerTree
*/
void decay(ShowerTreePtr tree, ShowerDecayMap & decay);
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:
/**
* 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 assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
QTildeShowerHandler & operator=(const QTildeShowerHandler &) = delete;
private:
/**
* Stuff from the ShowerHandler
*/
//@{
/**
* The ShowerTree for the hard process
*/
ShowerTreePtr hard_;
/**
* The ShowerTree for the decays
*/
ShowerDecayMap decay_;
/**
* The ShowerTrees for which the initial shower
*/
vector<ShowerTreePtr> done_;
//@}
private :
/**
* Pointer to the splitting generator
*/
SplittingGeneratorPtr _splittingGenerator;
/**
* Maximum number of tries to generate the shower of a particular tree
*/
unsigned int _maxtry;
/**
* Matrix element correction switch
*/
unsigned int _meCorrMode;
/**
* Control of the reconstruction option
*/
unsigned int _evolutionScheme;
/**
* If hard veto pT scale is being read-in this determines
* whether the read-in value is applied to primary and
* secondary (MPI) scatters or just the primary one, with
* the usual computation of the veto being performed for
* the secondary (MPI) scatters.
*/
bool _hardVetoReadOption;
/**
* rms intrinsic pT of Gaussian distribution
*/
Energy _iptrms;
/**
* Proportion of inverse quadratic intrinsic pT distribution
*/
double _beta;
/**
* Parameter for inverse quadratic: 2*Beta*Gamma/(sqr(Gamma)+sqr(intrinsicpT))
*/
Energy _gamma;
/**
* Upper bound on intrinsic pT for inverse quadratic
*/
Energy _iptmax;
/**
* Limit the number of emissions for testing
*/
unsigned int _limitEmissions;
/**
* The progenitor of the current shower
*/
ShowerProgenitorPtr _progenitor;
/**
* Matrix element
*/
HwMEBasePtr _hardme;
/**
* Decayer
*/
HwDecayerBasePtr _decayme;
/**
* The ShowerTree currently being showered
*/
ShowerTreePtr _currenttree;
/**
* The HardTree currently being showered
*/
HardTreePtr _hardtree;
/**
* Radiation enhancement factors for use with the veto algorithm
* if needed by the soft matrix element correction
*/
//@{
/**
* Enhancement factor for initial-state radiation
*/
double _initialenhance;
/**
* Enhancement factor for final-state radiation
*/
double _finalenhance;
//@}
/**
* The beam particle data for the current initial-state shower
*/
Ptr<BeamParticleData>::const_pointer _beam;
/**
* Storage of the intrinsic \f$p_t\f$ of the particles
*/
map<tShowerProgenitorPtr,pair<Energy,double> > _intrinsic;
/**
* Vetoes
*/
vector<ShowerVetoPtr> _vetoes;
/**
* Full Shower Vetoes
*/
vector<FullShowerVetoPtr> _fullShowerVetoes;
/**
* Number of iterations for reweighting
*/
unsigned int _nReWeight;
/**
* Whether or not we are reweighting
*/
bool _reWeight;
/**
* number of IS emissions
*/
unsigned int _nis;
/**
* Number of FS emissions
*/
unsigned int _nfs;
/**
* The option for wqhich interactions to use
*/
ShowerInteraction interaction_;
/**
* Truncated shower switch
*/
bool _trunc_Mode;
/**
* Mode for the hard emissions
*/
int _hardEmission;
/**
* Option for the kernal for soft correlations
*/
unsigned int _softOpt;
/**
* Option for hard radiation in POWHEG events
*/
bool _hardPOWHEG;
/**
* True if no warnings about incorrect hard emission
* mode setting have been issued yet
*/
static bool _hardEmissionWarn;
/**
* True if no warnings about missing truncated shower
* have been issued yet
*/
static bool _missingTruncWarn;
/**
* The relevant hard scale to be used in the profile scales
*/
Energy muPt;
private:
/**
* Pointer to the various objects
*/
//@{
/**
* Pointer to the KinematicsReconstructor object
*/
KinematicsReconstructorPtr _reconstructor;
/**
* Pointer to the PartnerFinder object
*/
PartnerFinderPtr _partnerfinder;
//@}
};
}
#endif /* HERWIG_QTildeShowerHandler_H */
diff --git a/Shower/QTilde/SplittingFunctions/HalfHalfZeroEWSplitFn.cc b/Shower/QTilde/SplittingFunctions/HalfHalfZeroEWSplitFn.cc
--- a/Shower/QTilde/SplittingFunctions/HalfHalfZeroEWSplitFn.cc
+++ b/Shower/QTilde/SplittingFunctions/HalfHalfZeroEWSplitFn.cc
@@ -1,243 +1,243 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the HalfHalfZeroEWSplitFn class.
//
#include "HalfHalfZeroEWSplitFn.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/ParticleData.h"
#include "Herwig/Decay/TwoBodyDecayMatrixElement.h"
#include "Herwig/Models/StandardModel/SMFFHVertex.h"
using namespace Herwig;
IBPtr HalfHalfZeroEWSplitFn::clone() const {
return new_ptr(*this);
}
IBPtr HalfHalfZeroEWSplitFn::fullclone() const {
return new_ptr(*this);
}
void HalfHalfZeroEWSplitFn::persistentOutput(PersistentOStream & os) const {
os << ghqq_ << _theSM;
}
void HalfHalfZeroEWSplitFn::persistentInput(PersistentIStream & is, int) {
is >> ghqq_ >> _theSM;
}
// The following static variable is needed for the type description system in ThePEG.
DescribeClass<HalfHalfZeroEWSplitFn,SplittingFunction>
describeHerwigHalfHalfZeroEWSplitFn("Herwig::HalfHalfZeroEWSplitFn", "HwShower.so");
void HalfHalfZeroEWSplitFn::Init() {
static ClassDocumentation<HalfHalfZeroEWSplitFn> documentation
("The HalfHalfZeroEWSplitFn class implements the splitting q->qH");
}
void HalfHalfZeroEWSplitFn::doinit() {
SplittingFunction::doinit();
tcSMPtr sm = generator()->standardModel();
double sw2 = sm->sin2ThetaW();
ghqq_ = 1./sqrt(4.*sw2);
_theSM = dynamic_ptr_cast<tcHwSMPtr>(generator()->standardModel());
}
void HalfHalfZeroEWSplitFn::getCouplings(double & gH, const IdList & ids) const {
if(abs(ids[2]->id())==ParticleID::h0) {
//get quark masses
Energy mq;
if(abs(ids[0]->id())==ParticleID::c)
mq = getParticleData(ParticleID::c)->mass();
else if(abs(ids[0]->id())==ParticleID::b)
mq = getParticleData(ParticleID::b)->mass();
else if(abs(ids[0]->id())==ParticleID::t)
mq = getParticleData(ParticleID::t)->mass();
Energy mW = getParticleData(ParticleID::Wplus)->mass();
gH = ghqq_*(mq/mW);
}
else
assert(false);
}
void HalfHalfZeroEWSplitFn::getCouplings(double & gH, const IdList & ids, const Energy2 t) const {
if(abs(ids[2]->id())==ParticleID::h0) {
//get quark masses
Energy mq;
if(abs(ids[0]->id())==ParticleID::c)
mq = _theSM->mass(t,getParticleData(ParticleID::c));
else if(abs(ids[0]->id())==ParticleID::b)
mq = _theSM->mass(t,getParticleData(ParticleID::b));
else if(abs(ids[0]->id())==ParticleID::t)
mq = _theSM->mass(t,getParticleData(ParticleID::t));
Energy mW = getParticleData(ParticleID::Wplus)->mass();
//Energy mW = _theSM->mass(t,getParticleData(ParticleID::Wplus));
gH = ghqq_*(mq/mW);
}
else
assert(false);
}
double HalfHalfZeroEWSplitFn::P(const double z, const Energy2 t,
- const IdList &ids, const bool mass, const RhoDMatrix & rho) const {
+ const IdList &ids, const bool mass, const RhoDMatrix &) const {
double gH(0.);
getCouplings(gH,ids,t);
double val = (1.-z);
Energy mq, mH;
//get masses
if(mass) {
mq = ids[0]->mass();
mH = ids[2]->mass();
}
else { // to assure the particle mass in non-zero
if(abs(ids[0]->id())==ParticleID::c)
mq = getParticleData(ParticleID::c)->mass();
else if(abs(ids[0]->id())==ParticleID::b)
mq = getParticleData(ParticleID::b)->mass();
else if(abs(ids[0]->id())==ParticleID::t)
mq = getParticleData(ParticleID::t)->mass();
mH = getParticleData(ParticleID::h0)->mass();
}
val += (4.*sqr(mq) - sqr(mH))/(t*(1. - z)*z);
val *= sqr(gH);
return colourFactor(ids)*val;
}
double HalfHalfZeroEWSplitFn::overestimateP(const double z,
const IdList & ids) const {
double gH(0.);
getCouplings(gH,ids);
return sqr(gH)*colourFactor(ids)*(1.-z);
}
double HalfHalfZeroEWSplitFn::ratioP(const double z, const Energy2 t,
const IdList & ids, const bool mass,
- const RhoDMatrix & rho) const {
+ const RhoDMatrix & ) const {
double gH(0.);
getCouplings(gH,ids,t);
double val = 1.;
Energy mq, mH;
if(mass) {
mq = ids[0]->mass();
mH = ids[2]->mass();
}
else { // to assure the particle mass in non-zero
if(abs(ids[0]->id())==ParticleID::c)
mq = getParticleData(ParticleID::c)->mass();
else if(abs(ids[0]->id())==ParticleID::b)
mq = getParticleData(ParticleID::b)->mass();
else if(abs(ids[0]->id())==ParticleID::t)
mq = getParticleData(ParticleID::t)->mass();
mH = getParticleData(ParticleID::h0)->mass();
}
val += (4.*sqr(mq) - sqr(mH))/(t*(1. - z)*z);
return val;
}
double HalfHalfZeroEWSplitFn::integOverP(const double z,
const IdList & ids,
unsigned int PDFfactor) const {
double gH(0.);
getCouplings(gH,ids);
double pre = colourFactor(ids)*sqr(gH);
switch (PDFfactor) {
case 0: //OverP
return pre*(z-sqr(z)/2.);
case 1: //OverP/z
return pre*(log(z)-z);
case 2: //OverP/(1-z)
return pre*z;
case 3: //OverP/[z(1-z)]
return pre*log(z);
default:
throw Exception() << "HalfHalfZeroEWSplitFn::integOverP() invalid PDFfactor = "
<< PDFfactor << Exception::runerror;
}
}
double HalfHalfZeroEWSplitFn::invIntegOverP(const double r, const IdList & ids,
unsigned int PDFfactor) const {
double gH(0.);
getCouplings(gH,ids);
double pre = colourFactor(ids)*sqr(gH);
switch (PDFfactor) {
case 0:
return 1. - sqrt(1. - 2.*r/pre);
case 1: //OverP/z
case 2: //OverP/(1-z)
return r/pre;
case 3: //OverP/[z(1-z)]
return exp(r/pre);
default:
throw Exception() << "HalfHalfZeroEWSplitFn::invIntegOverP() invalid PDFfactor = "
<< PDFfactor << Exception::runerror;
}
}
bool HalfHalfZeroEWSplitFn::accept(const IdList &ids) const {
if(ids.size()!=3) return false;
if(ids[2]->id()==ParticleID::h0) {
if(ids[0]->id()==ids[1]->id() && (ids[0]->id()==4 || ids[0]->id()==5 || ids[0]->id()==6))
return true;
}
return false;
}
vector<pair<int, Complex> >
HalfHalfZeroEWSplitFn::generatePhiForward(const double, const Energy2, const IdList & ,
const RhoDMatrix &) {
// no dependence on the spin density matrix, dependence on off-diagonal terms cancels
// and rest = splitting function for Tr(rho)=1 as required by defn
return vector<pair<int, Complex> >(1,make_pair(0,1.));
}
vector<pair<int, Complex> >
HalfHalfZeroEWSplitFn::generatePhiBackward(const double, const Energy2, const IdList & ,
const RhoDMatrix &) {
// no dependence on the spin density matrix, dependence on off-diagonal terms cancels
// and rest = splitting function for Tr(rho)=1 as required by defn
return vector<pair<int, Complex> >(1,make_pair(0,1.));
}
DecayMEPtr HalfHalfZeroEWSplitFn::matrixElement(const double z, const Energy2 t,
const IdList & ids, const double phi,
bool) {
// calculate the kernal
DecayMEPtr kernal(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1Half,PDT::Spin1Half,PDT::Spin0)));
//get masses
Energy mq, mH;
if(abs(ids[0]->id())==ParticleID::c)
mq = getParticleData(ParticleID::c)->mass();
else if(abs(ids[0]->id())==ParticleID::b)
mq = getParticleData(ParticleID::b)->mass();
else if(abs(ids[0]->id())==ParticleID::t)
mq = getParticleData(ParticleID::t)->mass();
mH = getParticleData(ParticleID::h0)->mass();
double gH(0.);
Energy2 tC = t/(z*(1-z));
getCouplings(gH,ids,tC);
double mqt = mq/sqrt(tC);
double mHt = mH/sqrt(tC);
double num1 = gH*(1.+z)*mqt;
double num2 = gH*sqrt(-sqr(mqt)*(1.-z) - sqr(mHt)*z + z*(1.-z)*(sqr(mqt)+z*(1.-z))); //watch this
double dnum = sqrt(2.)*sqrt((1.-z)*sqr(z));
Complex phase = exp(Complex(0.,1.)*phi);
Complex cphase = conj(phase);
(*kernal)(0,0,0) = num1/dnum;
(*kernal)(0,1,0) = cphase*num2/dnum;
(*kernal)(1,0,0) = -phase*num2/dnum;
(*kernal)(1,1,0) = num1/dnum;
// return the answer
return kernal;
}
diff --git a/Shower/QTilde/SplittingFunctions/OneOneOneQEDSplitFn.cc b/Shower/QTilde/SplittingFunctions/OneOneOneQEDSplitFn.cc
--- a/Shower/QTilde/SplittingFunctions/OneOneOneQEDSplitFn.cc
+++ b/Shower/QTilde/SplittingFunctions/OneOneOneQEDSplitFn.cc
@@ -1,236 +1,235 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the OneOneOneQEDSplitFn class.
//
#include "OneOneOneQEDSplitFn.h"
#include "ThePEG/StandardModel/StandardModelBase.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/ParticleData.h"
#include "Herwig/Decay/TwoBodyDecayMatrixElement.h"
#include "Herwig/Models/StandardModel/SMFFHVertex.h"
using namespace Herwig;
IBPtr OneOneOneQEDSplitFn::clone() const {
return new_ptr(*this);
}
IBPtr OneOneOneQEDSplitFn::fullclone() const {
return new_ptr(*this);
}
void OneOneOneQEDSplitFn::persistentOutput(PersistentOStream & os) const {
os << gWWG_ << _theSM;
}
void OneOneOneQEDSplitFn::persistentInput(PersistentIStream & is, int) {
is >> gWWG_ >> _theSM;
}
// The following static variable is needed for the type description system in ThePEG.
DescribeClass<OneOneOneQEDSplitFn,SplittingFunction>
describeHerwigOneOneOneQEDSplitFn("Herwig::OneOneOneQEDSplitFn", "HwShower.so");
void OneOneOneQEDSplitFn::Init() {
static ClassDocumentation<OneOneOneQEDSplitFn> documentation
("The OneOneOneQEDSplitFn class implements the gamma->WW EW splitting.");
}
void OneOneOneQEDSplitFn::doinit() {
SplittingFunction::doinit();
tcSMPtr sm = generator()->standardModel();
- double sw2 = sm->sin2ThetaW();
// WWG coupling
gWWG_ = 1.;
// to employ running masses, wherever needed
_theSM = dynamic_ptr_cast<tcHwSMPtr>(generator()->standardModel());
}
void OneOneOneQEDSplitFn::getCouplings(double & gvvv, const IdList & ids) const {
// G > WW
if(ids[0]->id()==ParticleID::gamma && abs(ids[1]->id())==ParticleID::Wplus
&& abs(ids[2]->id())==ParticleID::Wplus){
gvvv = gWWG_;
}
else
assert(false);
}
double OneOneOneQEDSplitFn::P(const double z, const Energy2 t,
const IdList &ids, const bool mass, const RhoDMatrix & rho) const {
double gvvv(0.);
getCouplings(gvvv,ids);
double abs_rho_00 = abs(rho(0,0));
double abs_rho_11 = abs(rho(1,1));
double abs_rho_22 = abs(rho(2,2));
// massless limit
double val = ((2.*sqr(1.-(1.-z)*z))/((1.-z)*z))*(abs_rho_00+abs_rho_22);
// massive limits
if(mass) {
double m0t2 = sqr(ids[0]->mass())/t;
double m1t2 = sqr(ids[1]->mass())/t;
double m2t2 = sqr(ids[2]->mass())/t;
val += (-2.*(m2t2*(1.-sqr(1.-z)*z)+m1t2*(1.-(1.-z)*sqr(z)))*(abs_rho_00+abs_rho_22))/((1.-z)*z)
+ (2.*m0t2*(2.*pow(1.-z,3)*z*abs_rho_11+sqr(1.-(1.-z)*z)*(abs_rho_00+abs_rho_22)))/((1.-z)*z);
}
return sqr(gvvv)*val;
}
double OneOneOneQEDSplitFn::overestimateP(const double z,
const IdList & ids) const {
double gvvv(0.);
getCouplings(gvvv,ids);
return sqr(gvvv)*(2./(z*(1.-z)));
}
double OneOneOneQEDSplitFn::ratioP(const double z, const Energy2 t,
const IdList & ids, const bool mass,
const RhoDMatrix & rho) const {
double val(0.);
double abs_rho_00 = abs(rho(0,0));
double abs_rho_11 = abs(rho(1,1));
double abs_rho_22 = abs(rho(2,2));
// massless limit
val = sqr(1.-(1.-z)*z)*(abs_rho_00+abs_rho_22);
// massive limit
if(mass) {
double m0t2 = sqr(ids[0]->mass())/t;
double m1t2 = sqr(ids[1]->mass())/t;
double m2t2 = sqr(ids[2]->mass())/t;
val += -(m2t2*(1.-sqr(1.-z)*z) + m1t2*(1.-(1.-z)*sqr(z)))*(abs_rho_00+abs_rho_22)
+ m0t2*(2.*pow(1.-z,3)*z*abs_rho_11+sqr(1.-(1.-z)*z)*(abs_rho_00+abs_rho_22));
}
return val;
}
double OneOneOneQEDSplitFn::integOverP(const double z,
const IdList & ids,
unsigned int PDFfactor) const {
double gvvv(0.);
getCouplings(gvvv,ids);
double pre = sqr(gvvv);
switch (PDFfactor) {
case 0:
return 2.*pre*(log(z)-log(1.-z));
case 1:
//return -2.*pre*(1./z+log(1.-z)-log(z));
case 2:
//return 2.*pre*(2.*log(z)+(2.*z-1.)/(z*(1.-z))-2.*log(1.-z));
case 3:
//return 2.*pre*(1./(1.-z)-1./z-2.*log(1.-z)+2.*log(z));
default:
throw Exception() << "OneOneOneQEDSplitFn::integOverP() invalid PDFfactor = "
<< PDFfactor << Exception::runerror;
}
}
double OneOneOneQEDSplitFn::invIntegOverP(const double r, const IdList & ids,
unsigned int PDFfactor) const {
double gvvv(0.);
getCouplings(gvvv,ids);
double pre = sqr(gvvv);
switch (PDFfactor) {
case 0:
return exp(0.5*r/pre)/(1.+exp(0.5*r/pre));
case 1:
case 2:
case 3:
default:
throw Exception() << "OneOneOneQEDSplitFn::invIntegOverP() invalid PDFfactor = "
<< PDFfactor << Exception::runerror;
}
}
bool OneOneOneQEDSplitFn::accept(const IdList &ids) const {
if(ids.size()!=3) return false;
if(ids[0]->id()==ParticleID::gamma && abs(ids[1]->id())==ParticleID::Wplus
&& ids[1]->id()==-ids[2]->id())
return true;
return false;
}
vector<pair<int, Complex> >
OneOneOneQEDSplitFn::generatePhiForward(const double, const Energy2, const IdList & ,
const RhoDMatrix &) {
// no dependence on the spin density matrix, dependence on off-diagonal terms cancels
// and rest = splitting function for Tr(rho)=1 as required by defn
return vector<pair<int, Complex> >(1,make_pair(0,1.));
}
vector<pair<int, Complex> >
OneOneOneQEDSplitFn::generatePhiBackward(const double, const Energy2, const IdList & ,
const RhoDMatrix &) {
// no dependence on the spin density matrix, dependence on off-diagonal terms cancels
// and rest = splitting function for Tr(rho)=1 as required by defn
return vector<pair<int, Complex> >(1,make_pair(0,1.));
}
DecayMEPtr OneOneOneQEDSplitFn::matrixElement(const double z, const Energy2 t,
const IdList & ids, const double phi,
bool) {
// calculate the kernal
DecayMEPtr kernal(new_ptr(TwoBodyDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin1)));
double gvvv(0.);
getCouplings(gvvv,ids);
// defining dummies
double m0t = ids[0]->mass()/sqrt(t);
double m1t = ids[1]->mass()/sqrt(t);
double m2t = ids[2]->mass()/sqrt(t);
Complex phase = exp(Complex(0.,1.)*phi);
Complex cphase = conj(phase);
double z1_z = z*(1.-z);
double sqrtmass = sqrt(sqr(m0t)-sqr(m1t)/z-sqr(m2t)/(1.-z)+1.);
double r2 = sqrt(2.);
// assign kernel
(*kernal)(0,0,0) = gvvv*phase*(1./sqrt(z1_z))*sqrtmass;
(*kernal)(0,0,1) = gvvv*r2*m2t*(z/(1.-z)); //2>4
(*kernal)(0,0,2) = -gvvv*cphase*sqrt(z/(1.-z))*sqrtmass;
(*kernal)(0,1,0) = -gvvv*r2*m1t*(1.-z)/z; //2>4
(*kernal)(0,1,1) = 0.;
(*kernal)(0,1,2) = 0.;
(*kernal)(0,2,0) = -gvvv*(1.-z)*cphase*sqrt((1.-z)/z)*sqrtmass;
(*kernal)(0,2,1) = 0.;
(*kernal)(0,2,2) = 0.;
(*kernal)(1,0,0) = 0.;
(*kernal)(1,0,1) = 0.; //2>4
(*kernal)(1,0,2) = -gvvv*r2*m0t*(1.-z); //2>4
(*kernal)(1,1,0) = 0.; //221>441
(*kernal)(1,1,1) = 0.; //222>444
(*kernal)(1,1,2) = 0.; //223>443
(*kernal)(1,2,0) = -gvvv*r2*m0t*(1.-z); //2>4
(*kernal)(1,2,1) = 0.; //2>4
(*kernal)(1,2,2) = 0.; //2>4
(*kernal)(2,0,0) = 0.;
(*kernal)(2,0,1) = 0.;
(*kernal)(2,0,2) = gvvv*(1.-z)*phase*sqrt((1.-z)/z)*sqrtmass;
(*kernal)(2,1,0) = 0.;
(*kernal)(2,1,1) = 0.; //2>4
(*kernal)(2,1,2) = -gvvv*r2*m1t*((1.-z)/z);//2>4
(*kernal)(2,2,0) = gvvv*phase*sqrt(z/(1.-z))*sqrtmass;
(*kernal)(2,2,1) = gvvv*r2*m2t*(z/(1.-z)); //2>4
(*kernal)(2,2,2) = -gvvv*cphase*(1./sqrt(z1_z))*sqrtmass;
// return the answer
return kernal;
}
diff --git a/Tests/Makefile.am b/Tests/Makefile.am
--- a/Tests/Makefile.am
+++ b/Tests/Makefile.am
@@ -1,393 +1,397 @@
AM_LDFLAGS += -module -avoid-version -rpath /dummy/path/not/used
EXTRA_DIST = Inputs python Rivet
EXTRA_LTLIBRARIES = LeptonTest.la GammaTest.la HadronTest.la DISTest.la
if WANT_LIBFASTJET
EXTRA_LTLIBRARIES += HadronJetTest.la LeptonJetTest.la
HadronJetTest_la_SOURCES = \
Hadron/VHTest.h Hadron/VHTest.cc\
Hadron/VTest.h Hadron/VTest.cc\
Hadron/HTest.h Hadron/HTest.cc
HadronJetTest_la_CPPFLAGS = $(AM_CPPFLAGS) $(FASTJETINCLUDE) \
-I$(FASTJETPATH)
HadronJetTest_la_LIBADD = $(FASTJETLIBS)
LeptonJetTest_la_SOURCES = \
Lepton/TopDecay.h Lepton/TopDecay.cc
LeptonJetTest_la_CPPFLAGS = $(AM_CPPFLAGS) $(FASTJETINCLUDE) \
-I$(FASTJETPATH)
LeptonJetTest_la_LIBADD = $(FASTJETLIBS)
endif
LeptonTest_la_SOURCES = \
Lepton/VVTest.h Lepton/VVTest.cc \
Lepton/VBFTest.h Lepton/VBFTest.cc \
Lepton/VHTest.h Lepton/VHTest.cc \
Lepton/FermionTest.h Lepton/FermionTest.cc
GammaTest_la_SOURCES = \
Gamma/GammaMETest.h Gamma/GammaMETest.cc \
Gamma/GammaPMETest.h Gamma/GammaPMETest.cc
DISTest_la_SOURCES = \
DIS/DISTest.h DIS/DISTest.cc
HadronTest_la_SOURCES = \
Hadron/HadronVVTest.h Hadron/HadronVVTest.cc\
Hadron/HadronVBFTest.h Hadron/HadronVBFTest.cc\
Hadron/WHTest.h Hadron/WHTest.cc\
Hadron/ZHTest.h Hadron/ZHTest.cc\
Hadron/VGammaTest.h Hadron/VGammaTest.cc\
Hadron/ZJetTest.h Hadron/ZJetTest.cc\
Hadron/WJetTest.h Hadron/WJetTest.cc\
Hadron/QQHTest.h Hadron/QQHTest.cc
REPO = $(top_builddir)/src/HerwigDefaults.rpo
HERWIG = $(top_builddir)/src/Herwig
HWREAD = $(HERWIG) read --repo $(REPO) -L $(builddir)/.libs -i $(top_builddir)/src
HWBUILD = $(HERWIG) build --repo $(REPO) -L $(builddir)/.libs -i $(top_builddir)/src
HWINTEGRATE = $(HERWIG) integrate
HWRUN = $(HERWIG) run -N $${NUMEVENTS:-10000}
tests : tests-LEP tests-DIS tests-LHC tests-Gamma
LEPDEPS = \
test-LEP-VV \
test-LEP-VH \
test-LEP-VBF \
test-LEP-BB \
test-LEP-Quarks \
test-LEP-Leptons
if WANT_LIBFASTJET
LEPDEPS += test-LEP-TopDecay
endif
tests-LEP : $(LEPDEPS)
tests-DIS : test-DIS-Charged test-DIS-Neutral
LHCDEPS = \
test-LHC-WW test-LHC-WZ test-LHC-ZZ \
test-LHC-ZGamma test-LHC-WGamma \
test-LHC-ZH test-LHC-WH \
test-LHC-ZJet test-LHC-WJet \
test-LHC-Z test-LHC-W \
test-LHC-ZZVBF test-LHC-VBF \
test-LHC-WWVBF \
test-LHC-bbH test-LHC-ttH \
test-LHC-GammaGamma test-LHC-GammaJet \
test-LHC-Higgs test-LHC-HiggsJet \
test-LHC-QCDFast test-LHC-QCD \
test-LHC-Top
if WANT_LIBFASTJET
LHCDEPS += \
test-LHC-Bottom \
test-LHC-WHJet test-LHC-ZHJet test-LHC-HJet \
test-LHC-ZShower test-LHC-WShower \
test-LHC-WHJet-Powheg test-LHC-ZHJet-Powheg test-LHC-HJet-Powheg \
test-LHC-ZShower-Powheg test-LHC-WShower-Powheg
endif
tests-LHC : $(LHCDEPS)
tests-Gamma : test-Gamma-FF test-Gamma-WW test-Gamma-P
LEPLIBS = LeptonTest.la
HADLIBS = HadronTest.la
if WANT_LIBFASTJET
LEPLIBS += LeptonJetTest.la
HADLIBS += HadronJetTest.la
endif
test-LEP-% : Inputs/LEP-%.in $(LEPLIBS)
$(HWREAD) $<
$(HWRUN) $(notdir $(subst .in,.run,$<))
test-Gamma-% : Inputs/Gamma-%.in GammaTest.la
$(HWREAD) $<
$(HWRUN) $(notdir $(subst .in,.run,$<))
test-DIS-% : Inputs/DIS-%.in DISTest.la
$(HWREAD) $<
$(HWRUN) $(notdir $(subst .in,.run,$<))
test-LHC-% : Inputs/LHC-%.in GammaTest.la $(HADLIBS)
$(HWREAD) $<
$(HWRUN) $(notdir $(subst .in,.run,$<))
tests-Rivet : Rivet-EE Rivet-DIS Rivet-Fixed \
Rivet-TVT-WZ Rivet-TVT-Photon Rivet-TVT-Jets \
Rivet-LHC-Jets Rivet-LHC-EW Rivet-LHC-Photon Rivet-LHC-Higgs
Rivet-%-UE-Cent.yoda : Rivet-%-UE-Cent.run Rivet-%-Cent.run
rm -rf $(subst .yoda,,$@)
mkdir $(subst .yoda,,$@)
mv $(subst .yoda,.run,$@) $(subst UE-,,$(subst .yoda,.run,$@)) $(subst .yoda,,$@)
cd $(subst .yoda,,$@); ../$(HWRUN) $(subst UE-,,$(subst .yoda,.run,$@)); mv $(subst UE-,,$@) ALICE_2015_PPCentrality.yoda
cd $(subst .yoda,,$@); export RIVET_ANALYSIS_PATH=`pwd`; ../$(HWRUN) $(subst .yoda,.run,$@)
mv $(subst .yoda,,$@)/$@ .
rm -rf $(subst .yoda,,$@)
Rivet-%.run : Rivet/%.in
$(HWBUILD) -c .cache/$(subst .run,,$@) $<
Rivet-Matchbox-%.yoda : Rivet-Matchbox-%.run
$(HWINTEGRATE) -c .cache/$(subst .run,,$<) $<
$(HWRUN) -c .cache/$(subst .run,,$<) $<
Rivet-%.yoda : Rivet-%.run
$(HWRUN) $<
Rivet/%.in :
python/make_input_files.py $(notdir $(subst .in,,$@))
-Rivet-inputfiles: $(shell echo Rivet/EE{,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{7.7,9.4,12,13,17,27.6,27.7,29,30.2,30.3,30.7,30.8,30,31.2,31.3,31.6,34,34.8,41,42.1,42.6,43.5,43.6,45,50,52,53.3,55,55.3,56,57,58,59.5,60.8,60,61.4,65.4,66,75.7,76,82,85,10,12.8,21.5,22,25,26.8,34.5,35,36.2,44,48.0,91,93.0,130,130.1,133,136,161,161.3,172,172.3,177,182.8,183,188.6,189,192,194.4,196,197,200,200.2,202,205,206,206.2,207,91-nopi}.in) \
+
+Rivet-inputfiles: $(shell echo Rivet/EE{,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{7.7,9.4,12,13,17,27.6,27.7,29,30.2,30.3,30.5,30.7,30.8,30,31.2,31.3,31.6,34,34.8,41,41.5,42.1,42.6,43.5,43.6,45,50,52,53.3,55,55.3,56,57,58,59.5,60.8,60,61.4,65.4,66,75.7,76,82,85,10,12.8,21.5,22,22.5,25,26.8,34.5,35,36.2,44,48.0,91,93.0,130,130.1,133,136,161,161.3,172,172.3,177,182.8,183,188.6,189,192,194.4,196,197,200,200.2,202,205,206,206.2,207,91-nopi}.in) \
+ $(shell echo Rivet/EE-{183,189}-WW.in) \
$(shell echo Rivet/EE{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Powheg,-Matchbox-Powheg}-{14,14.8}.in) \
$(shell echo Rivet/EE{,-Dipole}-{10.5,11.96,12.8,13.96,16.86,21.84,26.8,28.48,35.44,48.0,97.0}-gg.in) \
- $(shell echo Rivet/EE{,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg}-{2.2,2.6,3.0,3.2,4.17,4.3,4.41,5.0,5.2,4.6,4.8,5.8,6.2,6.6,7.0,7.4,3.63,4.03,4.5,8.8,9.27,9.46,9.51,10.52,10.52-sym,10.54,10.58,10.45,10.47,10.6}.in) \
- $(shell echo Rivet/EE-{Upsilon,Upsilon2,Upsilon3,Upsilon4,Upsilon4-asym,JPsi,Psi2S,Psi2S-All,Psi3770,Tau,Phi,Lambdac,Omega-Meson,Omega-Baryon,Eta,Xi0,Xic0,Xicp,Omegac0,Ds,Bc,Etac,Xim}.in) \
+ $(shell echo Rivet/EE{,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg}-{2.2,2.6,3.0,3.2,4.17,4.3,4.41,5.0,5.2,4.6,4.8,5.8,6.2,6.5,6.6,7.0,7.4,3.63,4.03,4.5,8.8,9.27,9.46,9.51,10.52,10.52-sym,10.54,10.58,10.45,10.47,10.6}.in) \
+ $(shell echo Rivet/EE-{Upsilon,Upsilon2,Upsilon3,Upsilon4,Upsilon5,Upsilon4-asym,JPsi,Psi2S,Psi2S-All,Psi3770,Tau,Phi,Lambdac,Omega-Meson,Omega-Baryon,Eta,Xi0,Xic0,Xicp,Omegac0,Ds,Bc,Etac,Xim}.in) \
$(shell echo Rivet/DIS{,-NoME,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{225,251,300,318,318-CMS}-e+-{VeryLow,Low,Med,High}Q2.in) \
$(shell echo Rivet/DIS{,-NoME,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-318-{e+,e-}-CC-{VeryLow,Low,Med,High}Q2.in) \
$(shell echo Rivet/DIS{,-NoME,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{296,300,318}-e--{VeryLow,Low,Med,High}Q2.in) \
$(shell echo Rivet/TVT{,-Powheg,-Matchbox,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox-Powheg,-Merging}-{Run-I-Z,Run-I-W,Run-I-WZ,Run-II-Z-e,Run-II-Z-{,LowMass-,HighMass-}mu,Run-II-W}.in) \
$(shell echo Rivet/TVT{,-Dipole}-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet,PromptPhoton}.in) \
$(shell echo Rivet/TVT-Powheg-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.in) \
$(shell echo Rivet/TVT{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-Run-{I,II}-{Jets-{1..6},DiJets-{1..4}}.in ) \
$(shell echo Rivet/TVT{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{630-Jets-{1..3},300-Jets-1,900-Jets-1}.in ) \
$(shell echo Rivet/TVT{,-Dipole}-{Run-I,Run-II,300,630,900}-UE.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-DiJets-{1..7}-{A,B,C}.in ) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-13-DiJets-{{1..11}-A,{6..11}-B}.in ) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{7,8,13}-Jets-{0..10}.in ) \
$(shell echo Rivet/LHC{,-Dipole}-{900,2360,2760,7,8,13}-UE.in ) \
- $(shell echo Rivet/LHC{,-Dipole}-{7,13}{,-UE}-Cent.in ) \
$(shell echo Rivet/LHC{,-Dipole}-2760-Jets-{1..3}.in ) \
$(shell echo Rivet/LHC{,-Dipole}-{900,7,13}-UE-Long.in ) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-Charm-{0..5}.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{5,13}-Charm-0.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-Bottom-{0..9}.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-13-Bottom-{0..6}.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-7-Top-{L,SL}.in) \
$(shell echo Rivet/LHC{,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Matchbox,-Matchbox-Powheg,-Merging}-{8,13}-Top-{All,L,SL}.in) \
$(shell echo Rivet/Star{,-Dipole}-{UE,Jets-{1..4}}.in ) \
$(shell echo Rivet/SppS{,-Dipole}-{53,63,200,500,546,900}-UE.in ) \
$(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{{,8-}W-{e,mu},13-W-mu,{,8-,13-}Z-{e,mu}-Mass{1..5},13-Z-nu,Z-mu-SOPHTY,WZ,WW-{emu,ll},13-WW-ll,13-ZZ-ll,ZZ-{ll,lv},{8,13}-WZ,8-ZZ-lv,8-WW-ll,Z-mu-Short}.in) \
$(shell echo Rivet/LHC{,-Dipole}-7-{W,Z}Gamma-{e,mu}.in) \
$(shell echo Rivet/LHC{,-Dipole}-8-ZGamma-{e,mu}.in) \
$(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{7-W-Jet-{1..3}-e,7-Z-Jet-{0..3}-e,7-Z-Jet-0-mu}.in) \
$(shell echo Rivet/LHC{-Matchbox,-Matchbox-Powheg,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{Z-b,Z-bb,8-Z-b,8-Z-bb,13-Z-b,13-Z-bb,W-b,8-Z-jj}.in) \
$(shell echo Rivet/LHC{,-Dipole}-{7,8,13}-PromptPhoton-{1..5}.in) Rivet/LHC-GammaGamma-7.in \
$(shell echo Rivet/LHC{,-Powheg,-Dipole}-{7,8,13}-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.in) \
$(shell echo Rivet/LHC{,-Powheg,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-{ggH,VBF,WH,ZH}.in) \
$(shell echo Rivet/LHC{,-Powheg,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-8-{{ggH,VBF,WH,ZH}{,-GammaGamma},ggH-WW}.in) \
$(shell echo Rivet/LHC{,-Matchbox,-Matchbox-Powheg,-Dipole,-Dipole-MCatNLO,-Dipole-Matchbox-Powheg,-Merging}-ggHJet.in) \
$(shell echo Rivet/ISR{,-Dipole}-{{30,44,53,62}-UE,{44,62}-Z-mu}.in Rivet/EHS{,-Dipole}-UE.in) \
$(shell echo Rivet/SPS{,-Dipole}-{17.4-UE,200-Z-mu}.in ) \
$(shell echo Rivet/Fermilab{,-Dipole}-{27.4,38.8}-Z-mu.in )
+#$(shell echo Rivet/LHC{,-Dipole}-{7,13}{,-UE}-Cent.in )
+
Rivet-GammaGamma: Rivet-GammaGamma/done
touch $@
Rivet-GammaGamma/done: $(shell echo Rivet-GammaGamma-mumu-{3.5,4.5,5.5,6.5,7.5,9.0,12.5,17.5,30.0}.yoda )
rm -rf Rivet-GammaGamma
python/merge-GammaGamma GammaGamma
rivet-mkhtml -o Rivet-GammaGamma GammaGamma.yoda:Hw
touch $@
Rivet-EE-Gamma: Rivet-EE-Gamma/done
touch $@
Rivet-EE-Gamma/done: $(shell echo Rivet-EE-Gamma-Direct-mumu-{161,172,183,189,196,206}.yoda ) \
$(shell echo Rivet-EE-Gamma-Direct-tautau-{189,196,206}.yoda ) \
$(shell echo Rivet-EE-Gamma-{Direct,Single-Resolved,Double-Resolved}-Jets-{198,206}.yoda )
rm -rf Rivet-EE-Gamma
python/merge-EE-Gamma EE-Gamma
rivet-mkhtml -o Rivet-EE-Gamma EE-Gamma.yoda:Hw
touch $@
Rivet-EE : Rivet-EE/done
touch $@
-Rivet-EE/done : $(shell echo Rivet{,-Powheg}-EE-{7.7,9.4,12,13,14,14.8,17,27.6,27.7,29,30.2,30.3,30.7,30.8,30,31.2,31.3,31.6,34,34.8,43.5,43.6,45,50,52,53.3,55,55.3,56,57,58,59.5,60.8,60,61.4,65.4,66,75.7,76,10,12.8,21.5,22,25,26.8,34.5,35,36.2,41,42.1,42.6,44,48.0,82,85,91,93.0,130,130.1,133,136,136.1,161,161.3,172,172.3,177,182.8,183,188.6,189,192,194.4,196,197,200,200.2,202,205,206,206.2,207,91-nopi}.yoda) \
- $(shell echo Rivet-EE-{10.5,11.96,12.8,13.96,16.86,21.84,26.8,28.48,35.44,48.0,97.0}-gg.yoda) \
- $(shell echo Rivet-EE-{10.52,10.52-sym,10.6,2.2,2.6,3.0,3.2,4.6,4.8,5.8,6.2,6.6,7.0,7.4,3.63,4.03,4.17,4.3,4.41,5.0,5.2,4.5,8.8,9.27,9.46,9.51,10.54,10.58,10.45,10.47,Upsilon,Upsilon2,Upsilon3,Upsilon4,Upsilon4-asym,Tau,Phi,Lambdac,Omega-Meson,Omega-Baryon,Eta,Xi0,Xic0,Xicp,Omegac0,Ds,Bc,Etac,Xim,JPsi,Psi2S,Psi2S-All,Psi3770}.yoda)
+Rivet-EE/done : $(shell echo Rivet{,-Powheg}-EE-{7.7,9.4,12,13,14,14.8,17,27.6,27.7,29,30.2,30.3,30.5,30.7,30.8,30,31.2,31.3,31.6,34,34.8,43.5,43.6,45,50,52,53.3,55,55.3,56,57,58,59.5,60.8,60,61.4,65.4,66,75.7,76,10,12.8,21.5,22,22.5,25,26.8,34.5,35,36.2,41,41.5,42.1,42.6,44,48.0,82,85,91,93.0,130,130.1,133,136,136.1,161,161.3,172,172.3,177,182.8,183,188.6,189,192,194.4,196,197,200,200.2,202,205,206,206.2,207,91-nopi}.yoda) \
+ $(shell echo Rivet-EE-{183,189}-WW.yoda) \
+ $(shell echo Rivet-EE-{10.5,11.96,12.8,13.96,16.86,21.84,26.8,28.48,35.44,48.0,97.0}-gg.yoda) \
+ $(shell echo Rivet-EE-{10.52,10.52-sym,10.6,2.2,2.6,3.0,3.2,4.6,4.8,5.8,6.2,6.5,6.6,7.0,7.4,3.63,4.03,4.17,4.3,4.41,5.0,5.2,4.5,8.8,9.27,9.46,9.51,10.54,10.58,10.45,10.47,Upsilon,Upsilon2,Upsilon3,Upsilon4,Upsilon5,Upsilon4-asym,Tau,Phi,Lambdac,Omega-Meson,Omega-Baryon,Eta,Xi0,Xic0,Xicp,Omegac0,Ds,Bc,Etac,Xim,JPsi,Psi2S,Psi2S-All,Psi3770}.yoda)
rm -rf Rivet-EE
- python/merge-EE --with-gg --with-decay EE
+ python/merge-EE --with-gg --with-decay --with-WW EE
python/merge-EE Powheg-EE
rivet-mkhtml -o Rivet-EE EE.yoda:Hw Powheg-EE.yoda:Hw-Powheg
python/plot-EE Rivet-EE
touch $@
Rivet-LowEnergy-%.yoda:
$(HWBUILD) -c .cache/$(subst .yoda,,$@) Rivet/$(subst .yoda,.in,$@)
$(HWRUN) $(subst .yoda,.run,$@)
Rivet-LowEnergy-EE-%:
args="--process "$(word 1,$(subst -, ,$(subst Rivet-LowEnergy-EE-,,$@))); if [ -n "$(strip $(word 2,$(subst -, ,$(subst Rivet-LowEnergy-EE-,,$@))))" ]; then args+=" --flavour "$(word 2,$(subst -, ,$(subst Rivet-LowEnergy-EE-,,$@))); fi; OUTPUT=`python/LowEnergy-EE.py $$args --non-perturbative --perturbative`; $(MAKE) $$OUTPUT NUMEVENTS=$${NUMEVENTS:-10000};
args="--process "$(word 1,$(subst -, ,$(subst Rivet-LowEnergy-EE-,,$@))); plots=`python/LowEnergy-EE.py $$args --plots`; python/mergeLowEnergy.py $(subst Rivet-LowEnergy-,,$@) $$plots; if [ -e LowEnergy-NonPerturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda ] && [ -e LowEnergy-Perturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-EE-$(subst Rivet-LowEnergy-EE-,,$@) LowEnergy-NonPerturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda:"Non-Pert" LowEnergy-Perturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda:"Pert" $$plots; elif [ -e LowEnergy-NonPerturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-EE-$(subst Rivet-LowEnergy-EE-,,$@) LowEnergy-NonPerturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda:"Non-Pert" $$plots; elif [ -e LowEnergy-Perturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-EE-$(subst Rivet-LowEnergy-EE-,,$@) LowEnergy-Perturbative-EE-$(subst Rivet-LowEnergy-EE-,,$@).yoda:"Pert" $$plots; fi
Rivet-LowEnergy-Photon-%:
args="--process "$(word 1,$(subst -, ,$(subst Rivet-LowEnergy-Photon-,,$@))); OUTPUT=`python/LowEnergy-Photon.py $$args --non-perturbative`; $(MAKE) $$OUTPUT NUMEVENTS=$${NUMEVENTS:-10000};
args="--process "$(word 1,$(subst -, ,$(subst Rivet-LowEnergy-Photon-,,$@))); plots=`python/LowEnergy-Photon.py $$args --plots`; python/mergeLowEnergy.py $(subst Rivet-LowEnergy-Photon-,GammaGamma-,$@) $$plots; if [ -e LowEnergy-NonPerturbative-GammaGamma-$(subst Rivet-LowEnergy-Photon-,,$@).yoda ] && [ -e LowEnergy-Perturbative-GammaGamma-$(subst Rivet-LowEnergy-Photon-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-Photon-$(subst Rivet-LowEnergy-Photon-,,$@) LowEnergy-NonPerturbative-GammaGamma-$(subst Rivet-LowEnergy-Photon-,,$@).yoda:"Non-Pert" LowEnergy-Perturbative-GammaGamma-$(subst Rivet-LowEnergy-Photon-,,$@).yoda:"Pert" $$plots; elif [ -e LowEnergy-NonPerturbative-GammaGamma-$(subst Rivet-LowEnergy-Photon-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-Photon-$(subst Rivet-LowEnergy-Photon-,,$@) LowEnergy-NonPerturbative-GammaGamma-$(subst Rivet-LowEnergy-Photon-,,$@).yoda:"Non-Pert" $$plots; elif [ -e LowEnergy-Perturbative-GammaGamma-$(subst Rivet-LowEnergy-Photon-,,$@).yoda ]; then rivet-mkhtml -o Rivet-LowEnergy-Photon-$(subst Rivet-LowEnergy-Photon-,,$@) LowEnergy-Perturbative-GammaGamma-$(subst Rivet-LowEnergy-Photon-,,$@).yoda:"Pert" $$plots; fi
Rivet-R:
OUTPUT=`python/R.py --perturbative --non-perturbative`; $(MAKE) $$OUTPUT NUMEVENTS=$${NUMEVENTS:-10000};
- plots=`python/R.py --perturbative --non-perturbative --plots`; python/mergeLowEnergy.py R $$plots; rivet-mkhtml -o Rivet-R LowEnergy-EE-Perturbative-R.yoda:"Pert" LowEnergy-EE-NonPerturbative-R.yoda:"Non-Pert" $$plots
+ plots=`python/R.py --perturbative --non-perturbative --plots`; python/mergeLowEnergy.py R $$plots; rivet-mkhtml -o Rivet-R LowEnergy-Perturbative-R.yoda:"Pert" LowEnergy-NonPerturbative-R.yoda:"Non-Pert" $$plots
Rivet-DIS : Rivet-DIS/done
touch $@
Rivet-DIS/done: $(shell echo Rivet{-DIS,-NoME-DIS,-Powheg-DIS}-{225,251,300,318,318-CMS}-e+-{VeryLow,Low,Med,High}Q2.yoda) \
$(shell echo Rivet{-DIS,-NoME-DIS,-Powheg-DIS}-{296,300,318}-e--{VeryLow,Low,Med,High}Q2.yoda) \
$(shell echo Rivet{-DIS,-NoME-DIS,-Powheg-DIS}-318-{e+,e-}-CC-{VeryLow,Low,Med,High}Q2.yoda)
rm -rf Rivet-DIS
python/merge-DIS DIS
python/merge-DIS Powheg-DIS
python/merge-DIS NoME-DIS
rivet-mkhtml -o Rivet-DIS DIS.yoda:Hw Powheg-DIS.yoda:Hw-Powheg NoME-DIS.yoda:Hw-NoME
touch $@
Rivet-TVT-EW : Rivet-TVT-EW/done
touch $@
Rivet-TVT-EW/done: $(shell echo Rivet{,-Powheg}-TVT-{Run-I-Z,Run-I-W,Run-I-WZ,Run-II-Z-{e,{,LowMass-,HighMass-}mu},Run-II-W}.yoda)
rm -rf Rivet-TVT-EW
python/merge-TVT-EW TVT
python/merge-TVT-EW Powheg-TVT
rivet-mkhtml -o Rivet-TVT-EW TVT-EW.yoda:Hw Powheg-TVT-EW.yoda:Hw-Powheg
touch $@
Rivet-TVT-Photon : Rivet-TVT-Photon/done
touch $@
Rivet-TVT-Photon/done: $(shell echo Rivet{,-Powheg}-TVT-Run-II-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.yoda Rivet-TVT-Run-II-PromptPhoton.yoda)
rm -rf Rivet-TVT-Photon
python/merge-TVT-Photon TVT
python/merge-TVT-Photon Powheg-TVT
rivet-mkhtml -o Rivet-TVT-Photon TVT-Photon.yoda:Hw Powheg-TVT-Photon.yoda:Hw-Powheg
touch $@
Rivet-TVT-Jets : Rivet-TVT-Jets/done
touch $@
Rivet-TVT-Jets/done: $(shell echo Rivet-TVT-Run-{I,II}-{Jets-{1..6},DiJets-{1..4}}.yoda ) \
$(shell echo Rivet-TVT-{630-Jets-{1..3},300-Jets-1,900-Jets-1}.yoda ) \
$(shell echo Rivet-TVT-{Run-I,Run-II,300,630,900}-UE.yoda)
rm -rf Rivet-TVT-Jets
python/merge-TVT-Jets TVT
rivet-mkhtml -o Rivet-TVT-Jets TVT-Jets.yoda:Hw
touch $@
Rivet-Fixed : Rivet-Fixed/done
touch $@
Rivet-Fixed/done : $(shell echo Rivet-SppS-{53,63,200,500,546,900}-UE.yoda ) \
$(shell echo Rivet-ISR-{{30,44,53,62}-UE,{44,62}-Z-mu}.yoda ) Rivet-EHS-UE.yoda \
$(shell echo Rivet-Star-{UE,Jets-{1..4}}.yoda ) \
$(shell echo Rivet-SPS-{17.4-UE,200-Z-mu}.yoda ) \
$(shell echo Rivet-Fermilab-{27.4,38.8}-Z-mu.yoda )
rm -rf Rivet-Fixed
python/merge-Fixed Fixed
rivet-mkhtml -o Rivet-Fixed Fixed.yoda:Hw
touch $@
Rivet-LHC-Jets : Rivet-LHC-Jets/done
touch $@
Rivet-LHC-Jets/done : \
$(shell echo Rivet-LHC-7-DiJets-{1..7}-{A,B,C}.yoda ) \
$(shell echo Rivet-LHC-13-DiJets-{{1..11}-A,{6..11}-B}.yoda ) \
$(shell echo Rivet-LHC-{7,8,13}-Jets-{0..10}.yoda ) \
$(shell echo Rivet-LHC-2760-Jets-{1..3}.yoda ) \
$(shell echo Rivet-LHC-{900,2360,2760,7,8,13}-UE.yoda ) \
- $(shell echo Rivet-LHC-{7,13}-UE-Cent.yoda ) \
$(shell echo Rivet-LHC-{900,7,13}-UE-Long.yoda ) \
$(shell echo Rivet-LHC-7-Charm-{0..5}.yoda ) \
- $(shell echo Rivet-LHC-{5-13}-Charm-0.yoda ) \
+ $(shell echo Rivet-LHC-{5,13}-Charm-0.yoda ) \
$(shell echo Rivet-LHC-7-Bottom-{0..9}.yoda ) \
$(shell echo Rivet-LHC-13-Bottom-{0..6}.yoda ) \
$(shell echo Rivet-LHC-{7,8,13}-Top-{L,SL}.yoda ) \
$(shell echo Rivet-LHC-{8,13}-Top-All.yoda )
+# $(shell echo Rivet-LHC-{7,13}-UE-Cent.yoda )
rm -rf Rivet-LHC-Jets
python/merge-LHC-Jets LHC
rivet-mkhtml -o Rivet-LHC-Jets LHC-Jets.yoda:Hw
touch $@
Rivet-LHC-EW : Rivet-LHC-EW/done
touch $@
Rivet-LHC-EW/done: \
$(shell echo Rivet{,-Powheg}-LHC-{{,8-}W-{e,mu},13-W-mu,{,8-,13-}Z-{e,mu}-Mass{1..5},13-Z-nu,Z-mu-SOPHTY,WZ,WW-{emu,ll},13-WW-ll,ZZ-{ll,lv},{8,13}-WZ,13-ZZ-ll,8-ZZ-lv,8-WW-ll,Z-mu-Short}.yoda) \
$(shell echo Rivet-LHC-{7-W-Jet-{1..3}-e,7-Z-Jet-{0..3}-e,7-Z-Jet-0-mu}.yoda) \
$(shell echo Rivet-LHC-7-{W,Z}Gamma-{e,mu}.yoda) \
$(shell echo Rivet-LHC-8-ZGamma-{e,mu}.yoda)
rm -rf Rivet-LHC-EW;
python/merge-LHC-EW LHC
python/merge-LHC-EW Powheg-LHC
rivet-mkhtml -o Rivet-LHC-EW LHC-EW.yoda:Hw Powheg-LHC-EW.yoda:Hw-Powheg \
Rivet-LHC-Z-mu-SOPHTY.yoda:Hw Rivet-Powheg-LHC-Z-mu-SOPHTY.yoda:Hw-Powheg
touch $@
Rivet-LHC-Photon : Rivet-LHC-Photon/done
touch $@
Rivet-LHC-Photon/done: \
$(shell echo Rivet-LHC-{7,8,13}-PromptPhoton-{1..5}.yoda) \
Rivet-LHC-GammaGamma-7.yoda \
$(shell echo Rivet{,-Powheg}-LHC-{7,8,13}-{DiPhoton-GammaGamma,DiPhoton-GammaJet}.yoda)
rm -rf Rivet-LHC-Photon
python/merge-LHC-Photon LHC
python/merge-LHC-Photon Powheg-LHC
rivet-mkhtml -o Rivet-LHC-Photon LHC-Photon.yoda:Hw Powheg-LHC-Photon.yoda:Hw-Powheg
touch $@
Rivet-LHC-Higgs : Rivet-LHC-Higgs/done
touch $@
Rivet-LHC-Higgs/done: \
$(shell echo Rivet{,-Powheg}-LHC-{ggH,VBF,WH,ZH}.yoda) \
$(shell echo Rivet{,-Powheg}-LHC-8-{{ggH,VBF,WH,ZH}{,-GammaGamma},ggH-WW}.yoda) \
Rivet-LHC-ggHJet.yoda
- yodamerge --add Rivet-Powheg-LHC-8-{ggH{-GammaGamma,-WW,},{VBF,ZH,WH}{,-GammaGamma}}.yoda -o Powheg-LHC-Higgs.yoda
- yodamerge --add Rivet-LHC-8-{ggH{-GammaGamma,-WW,},{VBF,ZH,WH}{,-GammaGamma}}.yoda -o LHC-Higgs.yoda
+ rivet-merge Rivet-Powheg-LHC-8-{ggH{-GammaGamma,-WW,},{VBF,ZH,WH}{,-GammaGamma}}.yoda -o Powheg-LHC-Higgs.yoda
+ rivet-merge Rivet-LHC-8-{ggH{-GammaGamma,-WW,},{VBF,ZH,WH}{,-GammaGamma}}.yoda -o LHC-Higgs.yoda
rm -rf Rivet-LHC-Higgs
rivet-mkhtml -o Rivet-LHC-Higgs Powheg-LHC-Higgs.yoda:Hw-Powheg LHC-Higgs.yoda:Hw\
Rivet-Powheg-LHC-ggH.yoda:gg-Powheg Rivet-LHC-ggH.yoda:gg Rivet-LHC-ggHJet.yoda:HJet \
Rivet-Powheg-LHC-VBF.yoda:VBF-Powheg Rivet-LHC-VBF.yoda:VBF Rivet-LHC-WH.yoda:WH Rivet-LHC-ZH.yoda:ZH \
Rivet-Powheg-LHC-WH.yoda:WH-Powheg Rivet-Powheg-LHC-ZH.yoda:ZH-Powheg
touch $@
clean-local:
rm -f *.out *.log *.tex *.top *.run *.dump *.mult *.Bmult *.yoda Rivet/*.in anatohepmc.txt hepmctoana.txt
rm -rf Rivet-*
distclean-local:
rm -rf .cache
diff --git a/Tests/Rivet/EE/EE-10.45.in b/Tests/Rivet/EE/EE-10.45.in
--- a/Tests/Rivet/EE/EE-10.45.in
+++ b/Tests/Rivet/EE/EE-10.45.in
@@ -1,12 +1,14 @@
# -*- ThePEG-repository -*-
create ThePEG::LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxA 5.225
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxB 5.225
set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 9.99
set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF
set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF
set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
# BELLE charm hadron production
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1993_S2789213
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1993_S2669951
+# CLEO Xi_c+ spectrum
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOII_1996_I404590
diff --git a/Tests/Rivet/EE/EE-10.52.in b/Tests/Rivet/EE/EE-10.52.in
--- a/Tests/Rivet/EE/EE-10.52.in
+++ b/Tests/Rivet/EE/EE-10.52.in
@@ -1,11 +1,10 @@
# -*- ThePEG-repository -*-
create ThePEG::LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxA 3.5*GeV
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxB 7.91*GeV
set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 9.99
set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF
set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF
set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
-
# BELLE charm hadron production
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2013_I1216515
diff --git a/Tests/Rivet/EE/EE-183-WW.in b/Tests/Rivet/EE/EE-183-WW.in
new file mode 100644
--- /dev/null
+++ b/Tests/Rivet/EE/EE-183-WW.in
@@ -0,0 +1,7 @@
+# -*- ThePEG-repository -*-
+##################################################
+# LEP physics parameters (override defaults)
+##################################################
+set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 183.
+# DELPHI particle spectra in WW
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 DELPHI_2001_I526164
diff --git a/Tests/Rivet/EE/EE-189-WW.in b/Tests/Rivet/EE/EE-189-WW.in
new file mode 100644
--- /dev/null
+++ b/Tests/Rivet/EE/EE-189-WW.in
@@ -0,0 +1,7 @@
+# -*- ThePEG-repository -*-
+##################################################
+# LEP physics parameters (override defaults)
+##################################################
+set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 189.
+# DELPHI particle spectra in WW
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 DELPHI_2001_I526164
diff --git a/Tests/Rivet/EE/EE-30.5.in b/Tests/Rivet/EE/EE-30.5.in
new file mode 100644
--- /dev/null
+++ b/Tests/Rivet/EE/EE-30.5.in
@@ -0,0 +1,13 @@
+# -*- ThePEG-repository -*-
+##################################################
+# LEP physics parameters (override defaults)
+##################################################
+set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 30.5
+set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 9.0
+##################################################
+# select the analyses
+##################################################
+# Validated
+##################################################
+# tasso event shapes at various energies
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 TASSO_1984_I195333
diff --git a/Tests/Rivet/EE/EE-41.5.in b/Tests/Rivet/EE/EE-41.5.in
new file mode 100644
--- /dev/null
+++ b/Tests/Rivet/EE/EE-41.5.in
@@ -0,0 +1,13 @@
+# -*- ThePEG-repository -*-
+##################################################
+# LEP physics parameters (override defaults)
+##################################################
+set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 41.5
+set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 9.0
+##################################################
+# select the analyses
+##################################################
+# Validated
+##################################################
+# tasso event shapes at various energies
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 TASSO_1984_I195333
diff --git a/Tests/Rivet/EE/EE-6.5.in b/Tests/Rivet/EE/EE-6.5.in
new file mode 100644
--- /dev/null
+++ b/Tests/Rivet/EE/EE-6.5.in
@@ -0,0 +1,13 @@
+# -*- ThePEG-repository -*-
+##################################################
+# LEP physics parameters (override defaults)
+##################################################
+set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy 6.5
+set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 2.0
+##################################################
+# select the analyses
+##################################################
+# Validated
+##################################################
+# MARK II charged spectrum
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MARKII_1982_I178416
diff --git a/Tests/Rivet/EE/EE-Bc.in b/Tests/Rivet/EE/EE-Bc.in
--- a/Tests/Rivet/EE/EE-Bc.in
+++ b/Tests/Rivet/EE/EE-Bc.in
@@ -1,18 +1,22 @@
# -*- ThePEG-repository -*-
create ThePEG::LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxA 6.5
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxB 6.5
set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 12.99999
set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF
set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF
set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so
set /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)
set /Herwig/MatrixElements/MEUpsilon:Coupling 96.72794
set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon
decaymode Upsilon(4S)->B_c+,B_c-; 1. 1 /Herwig/Decays/DecayME0
do /Herwig/Particles/Upsilon(4S):SelectDecayModes /Herwig/Particles/Upsilon(4S)/Upsilon(4S)->B_c+,B_c-;
# B_c -> Jpsi pi and 3pi
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 LHCB_2012_I1097092
# B_c -> Jpsi 3 hadrons
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 LHCB_2022_I1960979
+# B_c -> Jpsi/psi(2S) + hadrons
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 LHCB_2022_I2138845
+# B_c -> Jpsi/psi p pbar pi+
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 LHCB_2014_I1309880
diff --git a/Tests/Rivet/EE/EE-Lambdac.in b/Tests/Rivet/EE/EE-Lambdac.in
--- a/Tests/Rivet/EE/EE-Lambdac.in
+++ b/Tests/Rivet/EE/EE-Lambdac.in
@@ -1,37 +1,41 @@
# -*- ThePEG-repository -*-
create ThePEG::LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxA 5.2897*GeV
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxB 5.2897*GeV
set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 10.5792
set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF
set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF
set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so
set /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)
set /Herwig/MatrixElements/MEUpsilon:Coupling 96.72794
set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon
decaymode Upsilon(4S)->Lambda_c+,Lambdabar_c-; 1. 1 /Herwig/Decays/DecayME0
do /Herwig/Particles/Upsilon(4S):SelectDecayModes /Herwig/Particles/Upsilon(4S)/Upsilon(4S)->Lambda_c+,Lambdabar_c-;
# Lambda_c decays (Lambda Pi+)
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 FOCUS_2006_I693639
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1992_I319105
# Lambda_c decays (Lambda Pi+ and Sigma+ Pi0)
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_1995_I392704
# lambda_c -> Sigma + pi0,eta, eta'
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2022_I2140379
# Lambda_c decays Lambda,Sigma0 pi+,K+
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2022_I2138841
# Lambda_c decays (e+ nu_e)
# correlations
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1994_I371613
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOII_1994_I371611
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOII_2005_I668268
# pK- e+ nu_e
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2022_I2122399
# Lambda0 e+ nu_e
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2022_I2127373
# other decays
# Lambda_c -> Xi* K+ -> Xi- pi_ K+
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2008_I781294
# Lambda_c -> Lambda eta pi+
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2019_I1711896
+# Lambda_c -> p KS0 eta
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2021_I1837968
+# Lambda_c -> eta Lambda pi+
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2020_I1813380
diff --git a/Tests/Rivet/EE/EE-Psi3770.in b/Tests/Rivet/EE/EE-Psi3770.in
--- a/Tests/Rivet/EE/EE-Psi3770.in
+++ b/Tests/Rivet/EE/EE-Psi3770.in
@@ -1,129 +1,130 @@
# -*- ThePEG-repository -*-
# e+ e- -> psi(3770)
create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEPsi3770 HwMELepton.so
set /Herwig/MatrixElements/MEPsi3770:VectorMeson /Herwig/Particles/psi(3770)
set /Herwig/MatrixElements/MEPsi3770:Coupling 58.12041
set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEPsi3770
set EventGenerator:EventHandler:LuminosityFunction:Energy 3.7711
set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 0.2
set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF
set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF
########## branching ratios ################
# D0 inclusive
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 PDG_D0
# D+ inclusive
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 PDG_DPLUS
########## semi-leptonic ###################
# CLEO D lepton spectra
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOC_2009_I823313
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOC_2006_I715096
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOC_2008_I769777
# D0 -> K- semi-leptonic
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2018_I1697371
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2007_I1091435
# D+ -> eta
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOC_2011_I875526
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2018_I1662660
# D0/+ -> pi semi-leptonic
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2018_I1655158
# D0 -> Kbar0 pi- e+ nu_e
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2018_I1705754
# D -> pi pi e+ nu_e
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2019_I1694530
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2013_I1081165
# D0 -> pi- semi-leptonic
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2015_I1334693
# D0 -> pi-, K- semi-leptonic
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2015_I1391138
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2004_I654843
# D+ -> K0 pi0 semi-leptonic
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2017_I1519425
# D+ -> K- pi+ semi-leptonic
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2016_I1411645
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2010_I879997
# D+ -> omega l nu
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2015_I1386254
######### Two body decays ###################
# D0 -> omega phi
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2022_I1900094
########## 3-body decays ####################
# Dalitz plot analysis of D -> Kpipi decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 E691_1992_I342947
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MARKIII_1987_I247266
# Dalitz plot analysis of D0 -> KS0 pi0 pi0
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOC_2011_I913909
# Dalitz plot analysis of D+ -> K0S pi+ pi0
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2014_I1277070
# Dalitz plot analysis of D0 -> K0S pi+ pi-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2003_I633196
# Dalitz plot analysis of D+ -> K- pi+ pi+
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 E791_2002_I585322
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 FOCUS_2007_I750701
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOC_2008_I780363
# Kinematic distributions in the decay D0 -> K-pi+pi0
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOII_2001_I537154
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2006_I722905
# Dalitz decay of D0 -> K0S pi0 eta
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2004_I649917
# Dalitz decay of D0 -> K-pi+eta
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2020_I1785816
# D -> K pi omega
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2021_I1940222
# D -> K pi eta'
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2018_I1693610
# Dalitz plot analysis of D0 -> K0S K+ K-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2020_I1799437
# Dalitz plot analysis of D0 -> K0S pi+ pi- and D0 -> K0S K+ K-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2010_I853279
# Dalitz plot analysis of D+ -> K+K+K-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 LHCB_2019_I1720423
# Dalitz plot analysis of D+ -> K+ K- pi+
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2008_I791716
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2013_I1206605
# Dalitz plot analysis of D+ -> K+ K0S pi0
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2021_I1859124
# Dalitz plot analysis of D0 -> K+ K- pi0
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2007_I749390
# Dalitz plot analysis of D0 -> K0S K+- pi-+
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2012_I1094160
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 LHCB_2016_I1394391
# Dalitz decay of D+ and D+_s -> K+pi+pi-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 FOCUS_2004_I654030
# Dalitz plot analysis of D+ -> pi+ pi+ pi-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 E791_2001_I530320
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOC_2007_I749602
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 FOCUS_2003_I635446
# Dalitz plot analysis of D0 -> pi+ pi- pi0
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2007_I747154
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2016_I1441203
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2005_I679349
# D0 -> eta pi+pi-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOC_2008_I779705
# D0 -> pi0 eta eta
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2018_I1662665
########## Four body decays ####################
# D+ -> KS0 pi+pi+pi-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2019_I1714778
# D0 -> K- pi+ pi0 pi0
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2019_I1725265
# D0 -> K- pi+ pi+ pi-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2017_I1511280
# D+ -> KS0 pi+ pi0 pi0
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2022_I2088337
# D0 -> K-K-K+pi+
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 FOCUS_2003_I626320
# D0 -> K+ K- pi+ pi-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2012_I1086166
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 FOCUS_2004_I663820
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 LHCB_2018_I1704426
# D0 -> K+ K- pi+ pi- and 2pi+ 2pi-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2017_I1519168
# D0 -> 2pi+ 2pi-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 FOCUS_2007_I741543
# range of D+/D0 -> pion decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2022_I2102455
########## Spectra ##############################
# CLEO eta, eta' phi spectra in D decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOC_2006_I728043
########## psi(3770) decays ######################################
# Lambda Lambdabar correlations
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BESIII_2021_I1974025
diff --git a/Tests/Rivet/EE/EE-Upsilon4.in b/Tests/Rivet/EE/EE-Upsilon4.in
--- a/Tests/Rivet/EE/EE-Upsilon4.in
+++ b/Tests/Rivet/EE/EE-Upsilon4.in
@@ -1,100 +1,104 @@
# -*- ThePEG-repository -*-
create ThePEG::LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxA 5.2897*GeV
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxB 5.2897*GeV
set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 10.5792
set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF
set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF
set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so
set /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)
set /Herwig/MatrixElements/MEUpsilon:Coupling 96.72794
set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon
####### semileptonic decays #######################
# B0 -> D* l nu
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2017_I1512299
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2019_I1693396
# B0/B+ -> D l nu
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2015_I1397632
# B0 -> rho,pi B+ -> rho,omega
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2013_I1238273
+# B -> eho,pi ell nu
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2011_I855306
# B+ -> omega l nu
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2013_I1116411
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2013_I1247460
-# B to pi, eta, pmega
+# B to pi, eta, omega
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2012_I1125973
# B0 -> pi-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2011_I878990
# # BELLE B+ -> pi+pi- l nu
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2020_I1796822
# BELLE B0 -> D*- tau+ nu_tau D* polarization
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2019_I1724068
# BELLE B -> D* tau+ nu_tau tau polarization
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2018_I1621272
# BABAR e- spectrum
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2017_I1498564
# Crystal Ball e- spectrum
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CRYSTAL_BALL_1989_I263581
+# BELLE B-> Xu l nu
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2021_I1895149
############ b -> s gamma #################################
# BELLE b->s gamma
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2015_I1330289
# BABAR b->s gamma
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2008_I769107
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2012_I1123662
####### spectra ###################################
# ARGUS pi,K, proton
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1993_S2653028
# ARGUS K*, rho, omega
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1993_S2789213
# phi spectrum (CLEO and BaBar)
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2007_I728872
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2004_I632399
# D_s spectrum
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2005_I1649168
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2002_I582184
# ARGUS charm hadron production
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1991_I315059
# CLEO Xi_c spectrum
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOII_1997_I442910
# CLEO Sigma_c spectrum
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOII_1994_I361356
# CLEO baryon spectra
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_1992_I315181
# BABAR Omega_c spectra
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2007_I746745
# BABAR Xi'_c spectra
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2007_I722622
# multiplicities
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 PDG_Upsilon_4S_HADRON_MULTIPLICITIES
# CLEO multiplicty in Upsilon(4S) decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOII_1999_I504672
# kaons in b decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1994_I354224
# charm hadrons in b decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2006_I719111
# # MC analyses based on old internal ones
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_Meson_Meson_Leptons_Decay
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_D_Dalitz
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_Onium_PiPi_Decay
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 MC_Semi_Leptonic_Decay
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 ARGUS_1992_I319102
# BELLE Upsilon(4S) -> pi+pi- Upsilon(1S) decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2009_I810744
# BABAR Upsilon(4S) -> pi+pi- Upsilon(1,2S) decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2006_I714448
# CLEO J/psi and psi(2s) in b decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOII_2002_I606309
# BABAR eta' in b decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2004_I642355
# BELLE eta in b decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2010_I835104
# BELLE charm hadron producion
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2005_I686014
# BELLE Upsilon 4S -> Upsilon 1,2S pi+pi-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2017_I1610301
# BELLE B+ -> phi phi K+
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2021_I1841899
# BELLE B0 -> p pbar pi0
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2019_I1729311
# BELLE B0 -> KS0 K-+ pi+-
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2019_I1729723
diff --git a/Tests/Rivet/EE/EE-Upsilon5.in b/Tests/Rivet/EE/EE-Upsilon5.in
new file mode 100644
--- /dev/null
+++ b/Tests/Rivet/EE/EE-Upsilon5.in
@@ -0,0 +1,16 @@
+# -*- ThePEG-repository -*-
+create ThePEG::LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
+set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxA 5.4426*GeV
+set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxB 5.4426*GeV
+set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 10.885
+set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF
+set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF
+set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
+create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so
+set /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(5S)
+set /Herwig/MatrixElements/MEUpsilon:Coupling 0.001
+set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon
+# CLEO phi spectrum
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2007_I728872
+# D_s spectrum
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2005_I1649168
diff --git a/Tests/Rivet/EE/EE-Xic0.in b/Tests/Rivet/EE/EE-Xic0.in
--- a/Tests/Rivet/EE/EE-Xic0.in
+++ b/Tests/Rivet/EE/EE-Xic0.in
@@ -1,25 +1,26 @@
# -*- ThePEG-repository -*-
create ThePEG::LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxA 5.2897*GeV
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxB 5.2897*GeV
set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 10.5792
set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF
set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF
set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so
set /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)
set /Herwig/MatrixElements/MEUpsilon:Coupling 96.72794
set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon
decaymode Upsilon(4S)->Xi_c0,Xi_cbar0; 1. 1 /Herwig/Decays/DecayME0
do /Herwig/Particles/Upsilon(4S):SelectDecayModes /Herwig/Particles/Upsilon(4S)/Upsilon(4S)->Xi_c0,Xi_cbar0;
# Xi_c -> Xi- pi+ decay asymmetry
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEO_2000_I537236
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2021_I1851126
# Xi_c Lambda/Sigma K* asymmetries
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2021_I1859517
# Xi_c0 -> K+ K- Xi0
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2021_I1835729
# Omega decay asymmetries
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BABAR_2006_I719581
# Xi_c0 -> p K- K- pi+
-insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2005_I660759
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2005_I660759
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOIII_2004_I627327
diff --git a/Tests/Rivet/EE/EE-Xicp.in b/Tests/Rivet/EE/EE-Xicp.in
--- a/Tests/Rivet/EE/EE-Xicp.in
+++ b/Tests/Rivet/EE/EE-Xicp.in
@@ -1,16 +1,20 @@
# -*- ThePEG-repository -*-
create ThePEG::LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxA 5.2897*GeV
set /Herwig/EventHandlers/BFactoryLuminosity:BeamEMaxB 5.2897*GeV
set /Herwig/Generators/EventGenerator:EventHandler:Cuts:MHatMin 10.5792
set /Herwig/Particles/e-:PDF /Herwig/Partons/NoPDF
set /Herwig/Particles/e+:PDF /Herwig/Partons/NoPDF
set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction /Herwig/EventHandlers/BFactoryLuminosity
create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so
set /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)
set /Herwig/MatrixElements/MEUpsilon:Coupling 96.72794
set /Herwig/MatrixElements/SubProcess:MatrixElements 0 /Herwig/MatrixElements/MEUpsilon
decaymode Upsilon(4S)->Xi_c+,Xi_cbar-; 1. 1 /Herwig/Decays/DecayME0
do /Herwig/Particles/Upsilon(4S):SelectDecayModes /Herwig/Particles/Upsilon(4S)/Upsilon(4S)->Xi_c+,Xi_cbar-;
# Xi_c decays
insert /Herwig/Analysis/RivetAnalysis:Analyses 0 BELLE_2018_I1698390
+# Xi_c+ -> Sigma+ K- pi+
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 CLEOII_1996_I397787
+# Xi_c+ -> Sigma+ K- pi+, Xi- pi+ pi+
+insert /Herwig/Analysis/RivetAnalysis:Analyses 0 FOCUS_2003_I618864
diff --git a/Tests/python/HerwigInputs.py b/Tests/python/HerwigInputs.py
--- a/Tests/python/HerwigInputs.py
+++ b/Tests/python/HerwigInputs.py
@@ -1,263 +1,260 @@
# select the template to load
# collider
KNOWN_COLLIDERS = [
"EE-Gamma",
"BFactory",
"EE",
"DIS",
"TVT",
"LHC-GammaGamma",
"LHC",
"ISR",
"Fermilab",
"SppS",
"Star",
"SPS",
"GammaGamma",
]
def identifyCollider(name) :
""" Work out name of collider
"""
collider = ""
for cand_collider in KNOWN_COLLIDERS:
if cand_collider in name:
collider = cand_collider
break
del cand_collider
if "EHS" in name : collider="SPS"
assert collider
have_hadronic_collider = collider in ["TVT","LHC","ISR","SppS","Star","SPS","Fermilab"]
return (collider,have_hadronic_collider)
class StringBuilder(object):
"""
Avoid expensive string additions until the end
by building up a list first.
This helper class avoids rewriting all the += lower down
to list operations.
"""
def __init__(self, init = None):
self.lines = [] if init is None else [init]
def __iadd__(self, line):
self.lines.append(line)
return self
def __str__(self):
return '\n'.join(self.lines)
def identifySimulation(name,collider,have_hadronic_collider) :
""" Work out the type of simulation
Identify the parton shower and source of the matrix elements
"""
parameters = {
'shower' : '',
'bscheme' : '',
}
simulation=""
# istart determines how many name parts need to be skipped
istart = 1
# Dipole shower with Matchbox Powheg
if "Dipole-Matchbox-Powheg" in name :
istart = 4
simulation="Matchbox"
parameters["shower"] = "read Matchbox/Powheg-DipoleShower.in\n"
# Dipole shower with internal Powheg - Todo: Finish modifying template files.
'''
elif "Dipole-Powheg" in name :
istart = 3
simulation="Powheg"
parameters["shower"] = "set /Herwig/EventHandlers/EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler\nread snippets/Dipole_AutoTunes_gss.in\n"
'''
# Dipole shower with MCatNLO
elif "Dipole-MCatNLO" in name :
istart = 3
simulation="Matchbox"
parameters["shower"] = "read Matchbox/MCatNLO-DipoleShower.in\n"
# Dipole shower with Matchbox LO
elif "Dipole-Matchbox-LO" in name :
istart = 4
simulation="Matchbox"
parameters["shower"] = "read Matchbox/LO-DipoleShower.in\n"
# Dipole shower with internal LO
elif "Dipole" in name :
istart = 2
simulation=""
parameters["shower"] = "set /Herwig/EventHandlers/EventHandler:CascadeHandler /Herwig/DipoleShower/DipoleShowerHandler\nread snippets/Dipole_AutoTunes_gss.in\n"
# AO shower with Matchbox Powheg
elif "Matchbox-Powheg" in name :
istart = 3
simulation="Matchbox"
parameters["shower"] = "read Matchbox/Powheg-DefaultShower.in\n"
# AO shower with MCatNLO
elif "Matchbox" in name :
istart = 2
simulation="Matchbox"
parameters["shower"] = "read Matchbox/MCatNLO-DefaultShower.in\n"
# AO shower with internal Powheg
elif "Powheg" in name :
istart = 2
simulation="Powheg"
# Dipole shower with merging
elif "Merging" in name :
istart = 2
simulation="Merging"
thefactory="MergingFactory"
# Flavour settings for Matchbox
if simulation=="Matchbox" :
parameters["bscheme"] = "read Matchbox/FiveFlavourScheme.in\n"
if "Dipole" in parameters["shower"] :
parameters["bscheme"] += "read Matchbox/FiveFlavourNoBMassScheme.in\n"
if collider not in ['DIS','EE'] :
parameters["nlo"] = "read Matchbox/MadGraph-OpenLoops.in\n"
# Flavour settings for dipole shower with internal ME
if simulation=="" and "Dipole" in parameters["shower"] :
parameters["bscheme"] = "read snippets/DipoleShowerFiveFlavours.in"
# find the template
if simulation=="" :
if collider=="LHC-GammaGamma" :
istart += 1
templateName="Hadron-Gamma.in"
elif have_hadronic_collider :
templateName="Hadron.in"
elif collider=="EE-Gamma" :
istart+=1
if("Direct" in name) :
templateName="EE-Gamma-Direct.in"
elif("Single-Resolved" in name) :
templateName="EE-Gamma-Single-Resolved.in"
elif("Double-Resolved" in name) :
templateName="EE-Gamma-Double-Resolved.in"
else :
templateName="EE.in"
elif collider=="GammaGamma" :
templateName="GammaGamma.in"
elif collider != "BFactory" :
templateName= "%s.in" % collider
else :
templateName= "EE.in"
else :
if have_hadronic_collider :
templateName= "Hadron-%s.in" % simulation
elif collider != "BFactory" :
templateName= "%s-%s.in" % (collider,simulation)
else :
templateName= "EE-%s.in" % simulation
# work out the name of the parameter file
parameterName="-".join(name.split("-")[istart:])
del istart
return (simulation,templateName,parameterName,parameters)
def addLeptonPairCut(minmass,maxmass):
return "set /Herwig/Cuts/LeptonPairMassCut:MinMass %s*GeV\nset /Herwig/Cuts/LeptonPairMassCut:MaxMass %s*GeV\n" %(minmass,maxmass)
def setHardProcessWidthToZero(list1):
res=""
for i in list1:
res+="set /Herwig/Particles/"+i+":HardProcessWidth 0.\n"
return res
def jet_kt_cut(ktmin,ktmax=-1.):
output = "set /Herwig/Cuts/JetKtCut:MinKT {E}*GeV\n".format(E=ktmin)
if ktmax>0 :
output += "set /Herwig/Cuts/JetKtCut:MaxKT {E}*GeV\n".format(E=ktmax)
return output
def mhat_cut(mmin,mmax=-1):
output = "set /Herwig/Cuts/Cuts:MHatMin {E}*GeV\n".format(E=mmin)
if mmax>0. :
output += "set /Herwig/Cuts/Cuts:MHatMax {E}*GeV\n".format(E=mmax)
return output
def mhat_minm_maxm(e1,e2,e3):
return """\
set /Herwig/Cuts/Cuts:MHatMin {e1}*GeV
set /Herwig/Cuts/MassCut:MinM {e2}*GeV
set /Herwig/Cuts/MassCut:MaxM {e3}*GeV
""".format(**locals())
def collider_lumi(energy):
return "set /Herwig/Generators/EventGenerator:EventHandler:LuminosityFunction:Energy {E}*GeV\n".format(E=energy)
def insert_ME(me,process=None,ifname='Process',subprocess="SubProcess"):
result = "insert /Herwig/MatrixElements/{subprocess}:MatrixElements 0 /Herwig/MatrixElements/{me}\n".format(**locals())
if process is not None:
- if me=="MEgg2ff" :
- result += "set /Herwig/MatrixElements/gg2ffAmp:{ifname} {process}".format(**locals())
- else :
- result += "set /Herwig/MatrixElements/{me}:{ifname} {process}".format(**locals())
+ result += "set /Herwig/MatrixElements/{me}:{ifname} {process}".format(**locals())
return result
def particlegroup(factory,name,*particles):
directory="MatrixElements/Matchbox"
if(factory!="Factory") : directory="Merging"
result = ["do /Herwig/{dir}/{fact}:StartParticleGroup {n}".format(n=name,fact=factory,dir=directory)]
for p in particles:
result.append(
"insert /Herwig/{dir}/{fact}:ParticleGroup 0 /Herwig/Particles/{p}".format(p=p,fact=factory,dir=directory)
)
result.append("do /Herwig/{dir}/{fact}:EndParticleGroup".format(fact=factory,dir=directory))
return '\n'.join(result)
didaddfirstjet=False
def addFirstJet(ptcut,ptmax=""):
global didaddfirstjet
if(didaddfirstjet):
logging.error("Can only add jetcut once.")
sys.exit(1)
res="set /Herwig/Cuts/Cuts:JetFinder /Herwig/Cuts/JetFinder\n"
res+="insert /Herwig/Cuts/Cuts:MultiCuts 0 /Herwig/Cuts/JetCuts\n"
res+="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/FirstJet\n"
if(ptcut!=""):
res+="set /Herwig/Cuts/FirstJet:PtMin %s*GeV\n" % ptcut
if(ptmax!=""):
res+="set /Herwig/Cuts/FirstJet:PtMax %s*GeV\n" % ptmax
didaddfirstjet=True
return res
didaddsecondjet=False
def addSecondJet(ptcut):
global didaddsecondjet
if(didaddsecondjet):
logging.error("Can only add second jetcut once.")
sys.exit(1)
res="insert /Herwig/Cuts/JetCuts:JetRegions 0 /Herwig/Cuts/SecondJet\n"
res+="set /Herwig/Cuts/SecondJet:PtMin "+ptcut+"*GeV\n"
didaddsecondjet=True
return res
didaddjetpair=False
def addJetPairCut(minmass,maxmass=""):
global didaddjetpair
if(didaddjetpair):
logging.error("Can only add second jetcut once.")
sys.exit(1)
res="""\
create ThePEG::JetPairRegion /Herwig/Cuts/JetPairMass JetCuts.so
set /Herwig/Cuts/JetPairMass:FirstRegion /Herwig/Cuts/FirstJet
set /Herwig/Cuts/JetPairMass:SecondRegion /Herwig/Cuts/SecondJet
insert /Herwig/Cuts/JetCuts:JetPairRegions 0 /Herwig/Cuts/JetPairMass
set /Herwig/Cuts/JetPairMass:MassMin {mm}*GeV
""".format(mm=minmass)
if maxmass != "" :
res+= "set /Herwig/Cuts/JetPairMass:MassMin %s*GeV\n" %maxmass
didaddjetpair=True
return res
diff --git a/Tests/python/LowEnergy-EE.py.in b/Tests/python/LowEnergy-EE.py.in
--- a/Tests/python/LowEnergy-EE.py.in
+++ b/Tests/python/LowEnergy-EE.py.in
@@ -1,553 +1,553 @@
#! @PYTHON@
from __future__ import print_function
import yoda,os,math,subprocess,optparse
from string import Template
# get the path for the rivet data
p = subprocess.Popen(["rivet-config", "--datadir"],stdout=subprocess.PIPE)
path=p.communicate()[0].strip().decode("UTF-8")
#Define the arguments
op = optparse.OptionParser(usage=__doc__)
op.add_option("--process" , dest="processes" , default=[], action="append")
op.add_option("--path" , dest="path" , default=path)
op.add_option("--non-perturbative", dest="nonPerturbative" , default=False, action="store_true")
op.add_option("--perturbative" , dest="perturbative" , default=False, action="store_true")
op.add_option("--dest" , dest="dest" , default="Rivet")
op.add_option("--list" , dest="list" , default=False, action="store_true")
op.add_option("--flavour" , dest="flavour" , default="All" )
op.add_option("--plots" , dest="plot" , default=False, action="store_true")
opts, args = op.parse_args()
path=opts.path
thresholds = [0.7,2.*.5,2.*1.87,2.*5.28]
# the list of analyses and processes
analyses = { 'KK' : {}, 'PiPi' : {}, 'PPbar' : {}, "3Pi" : {},
"EtaprimePiPi" : {}, "4Pi" : {}, "EtaPhi" : {}, "EtaOmega" : {},
"2K1Pi" : {}, "2K2Pi" : {}, "4K" : {}, "6m" : {},
"EtaPiPi" : {}, "OmegaPi" : {}, "PiGamma" : {}, "EtaGamma" : {},
"PhiPi" : {}, "OmegaPiPi" : {}, "DD" : {}, "BB" : {},
"5Pi" : {}, "LL" : {}, "Baryon" : {} }
# pi+pi-
analyses["PiPi"]["KLOE_2009_I797438" ] = ["d02-x01-y01"]
analyses["PiPi"]["KLOE_2005_I655225" ] = ["d02-x01-y01"]
analyses["PiPi"]["KLOE2_2017_I1634981" ] = ["d01-x01-y01"]
analyses["PiPi"]["BABAR_2009_I829441" ] = ["d01-x01-y01"]
analyses["PiPi"]["DM1_1978_I134061" ] = ["d01-x01-y01"]
analyses["PiPi"]["DM2_1989_I267118" ] = ["d01-x01-y01"]
analyses["PiPi"]["CMD2_2007_I728302" ] = ["d02-x01-y01"]
analyses["PiPi"]["CMD2_2006_I728191" ] = ["d03-x01-y01"]
analyses["PiPi"]["BESIII_2016_I1385603"] = ["d01-x01-y01"]
analyses["PiPi"]["SND_2005_I686349" ] = ["d01-x01-y01"]
analyses["PiPi"]["CMD_1985_I221309" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["PiPi"]["CMD2_2002_I568807" ] = ["d01-x01-y02"]
analyses["PiPi"]["CMD2_1999_I498859" ] = ["d01-x01-y01"]
analyses['PiPi']["CLEOC_2005_I693873" ] = ["d01-x01-y01"]
analyses['PiPi']["ND_1991_I321108" ] = ["d11-x01-y01"]
analyses['PiPi']["OLYA_1984_I208231" ] = ["d01-x01-y01"]
analyses['PiPi']["SND_2020_I1789269" ] = ["d01-x01-y04"]
# K+K- and K_S^0 K_L^0
analyses['KK']["BESIII_2018_I1704558"] = ["d01-x01-y01"]
analyses['KK']["BABAR_2013_I1238807" ] = ["d01-x01-y01"]
analyses['KK']["DM1_1981_I156053" ] = ["d01-x01-y01"]
analyses['KK']["DM1_1981_I156054" ] = ["d01-x01-y01"]
analyses['KK']["CLEOC_2005_I693873" ] = ["d01-x01-y02"]
analyses['KK']["BABAR_2015_I1383130" ] = ["d01-x01-y04"]
analyses['KK']["DM2_1988_I262690" ] = ["d01-x01-y01"]
analyses['KK']["SND_2007_I755881" ] = ["d01-x01-y01"]
analyses['KK']["SND_2001_I533574" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03",
"d02-x01-y01","d02-x01-y02","d02-x01-y03"]
analyses['KK']["SND_2006_I720035" ] = ["d01-x01-y01"]
analyses['KK']["BABAR_2014_I1287920" ] = ["d09-x01-y01"]
analyses['KK']["CMD2_2003_I601222" ] = ["d01-x01-y01"]
analyses['KK']["CMD3_2016_I1444990" ] = ["d01-x01-y06"]
analyses['KK']["CMD2_1995_I406880" ] = ["d01-x01-y01","d01-x01-y02"]
analyses['KK']["CMD2_1999_I502164" ] = ["d01-x01-y01","d02-x01-y01",
"d03-x01-y01","d04-x01-y01"]
analyses['KK']["CMD2_2008_I782516" ] = ["d01-x01-y01","d02-x01-y01"]
analyses['KK']["ND_1991_I321108" ] = ["d12-x01-y01","d13-x01-y01"]
analyses['KK']["OLYA_1981_I173076" ] = ["d01-x01-y01"]
analyses['KK']["SND_2016_I1484677" ] = ["d01-x01-y01","d02-x01-y01"]
analyses['KK']["BABAR_2020_I1769654" ] = ["d01-x01-y01"]
analyses['KK']["BESIII_2021_I1866051"] = ["d01-x01-y01"]
# proton-antiproton
analyses['PPbar']["BESIII_2021_I1966612"] = ["d01-x01-y01"]
analyses['PPbar']["BESIII_2019_I1736235"] = ["d01-x01-y01"]
analyses['PPbar']["BESIII_2019_I1718337"] = ["d01-x01-y01"]
analyses['PPbar']["BESIII_2015_I1358937"] = ["d01-x01-y05"]
analyses['PPbar']["BABAR_2013_I1217421" ] = ["d01-x01-y01"]
analyses['PPbar']["BABAR_2013_I1247058" ] = ["d01-x01-y01"]
analyses['PPbar']["SND_2014_I1321689" ] = ["d01-x01-y01","d02-x01-y01"]
analyses['PPbar']["CMD3_2016_I1385598" ] = ["d01-x01-y06"]
analyses['PPbar']["CLEOC_2005_I693873" ] = ["d01-x01-y03"]
analyses['PPbar']["BABAR_2006_I700020" ] = ["d01-x01-y01","d02-x01-y01"]
analyses['PPbar']["DM2_1983_I190558" ] = ["d01-x01-y01"]
analyses["PPbar"]["DM2_1990_I297706" ] = ["d01-x01-y01"]
analyses["PPbar"]["DM1_1979_I141565" ] = ["d01-x01-y01"]
analyses["PPbar"]["FENICE_1998_I471263" ] = ["d01-x01-y01"]
analyses["PPbar"]["FENICE_1994_I377833" ] = ["d01-x01-y01"]
analyses['PPbar']["BESII_2005_I685906" ] = ["d01-x01-y01"]
analyses['PPbar']["BESIII_2014_I1286898"] = ["d01-x01-y06"]
analyses['PPbar']["BESIII_2021_I1853007"] = ["d01-x01-y01"]
analyses['PPbar']["BESIII_2021_I1847766"] = ["d01-x01-y01"]
# pi0 gamma
analyses["PiGamma"]["SND_2018_I1694988"] = ["d01-x01-y01"]
analyses["PiGamma"]["SND_2016_I1418483"] = ["d01-x01-y05"]
analyses["PiGamma"]["SND_2003_I612867" ] = ["d01-x01-y01"]
analyses["PiGamma"]["CMD2_2005_I658856"] = ["d02-x01-y01"]
analyses["PiGamma"]["SND_2000_I524221" ] = ["d01-x01-y02"]
# eta gamma
analyses["EtaGamma"]["CMD2_2005_I658856" ] = ["d01-x01-y01"]
analyses["EtaGamma"]["SND_2006_I717778" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["EtaGamma"]["SND_2014_I1275333" ] = ["d01-x01-y01"]
analyses["EtaGamma"]["SND_2000_I524221" ] = ["d01-x01-y01"]
analyses["EtaGamma"]["CMD2_1999_I503154" ] = ["d01-x01-y01"]
analyses["EtaGamma"]["CMD2_2001_I554522" ] = ["d01-x01-y01"]
analyses['EtaGamma']["CMD2_1995_I406880" ] = ["d01-x01-y04"]
analyses['EtaGamma']["BABAR_2006_I716277"] = ["d01-x01-y01"]
# 3 pion
analyses["3Pi"]["BABAR_2004_I656680" ] = ["d01-x01-y01"]
analyses["3Pi"]["BABAR_2021_I1937349" ] = ["d01-x01-y01"]
analyses["3Pi"]["BESIII_2019_I1773081" ] = ["d01-x01-y01"]
analyses["3Pi"]["SND_2002_I582183" ] = ["d01-x01-y01"]
analyses["3Pi"]["SND_2003_I619011" ] = ["d01-x01-y01"]
analyses["3Pi"]["SND_1999_I508003" ] = ["d01-x01-y01"]
analyses["3Pi"]["SND_2001_I533574" ] = ["d01-x01-y04","d02-x01-y04"]
analyses["3Pi"]["CMD2_2000_I523691" ] = ["d01-x01-y01"]
analyses["3Pi"]["CMD2_1998_I480170" ] = ["d01-x01-y01"]
analyses['3Pi']["CMD2_1995_I406880" ] = ["d01-x01-y03"]
analyses['3Pi']["DM2_1992_I339265" ] = ["d01-x01-y01"]
analyses['3Pi']["DM1_1980_I140174" ] = ["d01-x01-y01"]
analyses['3Pi']["ND_1991_I321108" ] = ["d05-x01-y01","d10-x01-y04"]
analyses['3Pi']["GAMMAGAMMA_1981_I158474"] = ["d01-x01-y01"]
analyses["3Pi"]["CLEO_2006_I691720" ] = ["d01-x01-y01"]
analyses["3Pi"]["SND_2015_I1389908" ] = ["d01-x01-y01"]
analyses["3Pi"]["SND_2020_I1809286" ] = ["d01-x01-y01","d02-x01-y01",
"d03-x01-y01","d03-x01-y02","d03-x01-y03"]
# eta pipi
analyses["EtaPiPi"]["BABAR_2007_I758568" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["EtaPiPi"]["BABAR_2018_I1647139" ] = ["d01-x01-y01"]
analyses["EtaPiPi"]["BABAR_2018_I1700745" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["EtaPiPi"]["BESIII_2022_I2039027"] = ["d01-x01-y01","d02-x01-y01"]
analyses["EtaPiPi"]["CMD2_2000_I532970" ] = ["d02-x01-y01"]
analyses['EtaPiPi']["CMD3_2019_I1744510" ] = ["d02-x01-y01"]
analyses["EtaPiPi"]["DM2_1988_I264144" ] = ["d01-x01-y01"]
analyses['EtaPiPi']["ND_1991_I321108" ] = ["d06-x01-y01","d14-x01-y01"]
analyses["EtaPiPi"]["SND_2015_I1332929" ] = ["d01-x01-y01"]
analyses["EtaPiPi"]["SND_2018_I1638368" ] = ["d01-x01-y01"]
# eta' pipi
analyses["EtaprimePiPi"]["BABAR_2007_I758568" ] = ["d05-x01-y01","d06-x01-y01"]
analyses["EtaprimePiPi"]["BESIII_2020_I1836509"] = ["d01-x01-y01"]
# Eta Phi
analyses["EtaPhi"]["BABAR_2006_I709730" ] = ["d02-x01-y01"]
analyses["EtaPhi"]["BABAR_2006_I731865" ] = ["d01-x01-y02"]
analyses["EtaPhi"]["BABAR_2007_I758568" ] = ["d08-x01-y01","d09-x01-y01"]
analyses["EtaPhi"]["BABAR_2008_I765258" ] = ["d04-x01-y01","d05-x01-y01"]
analyses["EtaPhi"]["BABAR_2017_I1511276" ] = ["d03-x01-y01"]
analyses["EtaPhi"]["BABAR_2022_I2120528" ] = ["d04-x01-y01","d05-x01-y01"]
analyses["EtaPhi"]["BELLE_2009_I823878" ] = ["d01-x01-y01"]
analyses["EtaPhi"]["BESII_2008_I801210" ] = ["d01-x01-y03"]
analyses["EtaPhi"]["BESIII_2021_I1857930"] = ["d01-x01-y01"]
analyses["EtaPhi"]["CMD3_2017_I1606078" ] = ["d01-x01-y01"]
analyses["EtaPhi"]["CMD3_2019_I1740541" ] = ["d01-x01-y06","d02-x01-y06","d03-x01-y06"]
analyses["EtaPhi"]["SND_2018_I1693737" ] = ["d01-x01-y01"]
analyses["EtaPhi"]["SND_2019_I1726419" ] = ["d01-x01-y01","d01-x01-y03"]
analyses["EtaPhi"]["SND_2021_I1942539" ] = ["d01-x01-y01"]
# Eta Omega
analyses["EtaOmega"]["BABAR_2006_I709730" ] = ["d02-x01-y01"]
analyses["EtaOmega"]["BABAR_2021_I1938254" ] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01","d04-x01-y01"]
analyses["EtaOmega"]["BESII_2008_I801210" ] = ["d01-x01-y03"]
analyses["EtaOmega"]["BESIII_2020_I1817739"] = ["d01-x01-y01"]
analyses["EtaOmega"]["BESIII_2022_I2047667"] = ["d01-x01-y02"]
analyses["EtaOmega"]["CMD3_2017_I1606078" ] = ["d01-x01-y01","d01-x01-y02"]
analyses["EtaOmega"]["SND_2016_I1473343" ] = ["d01-x01-y01"]
analyses["EtaOmega"]["SND_2019_I1726419" ] = ["d01-x01-y01","d01-x01-y02"]
analyses["EtaOmega"]["SND_2020_I1800477" ] = ["d01-x01-y01","d03-x01-y01"]
# 4 pions
analyses["4Pi"]["BABAR_2017_I1621593" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["4Pi"]["BABAR_2012_I1086164" ] = ["d01-x01-y01"]
analyses["4Pi"]["CMD2_2000_I531667" ] = ["d01-x01-y01"]
analyses["4Pi"]["CMD2_2004_I648023" ] = ["d01-x01-y01"]
analyses["4Pi"]["BABAR_2005_I676691" ] = ["d01-x01-y01"]
analyses["4Pi"]["CMD2_2000_I511375" ] = ["d01-x01-y01"]
analyses["4Pi"]["CMD2_1999_I483994" ] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01"]
analyses["4Pi"]["BESII_2008_I801210" ] = ["d01-x01-y01"]
analyses["4Pi"]["BESIII_2022_I2047667" ] = ["d01-x01-y01"]
analyses["4Pi"]["KLOE_2008_I791841" ] = ["d01-x01-y01"]
analyses['4Pi']["ND_1991_I321108" ] = ["d07-x01-y01","d08-x01-y01","d10-x01-y01","d10-x01-y02",
"d01-x01-y01","d02-x01-y01","d03-x01-y01","d04-x01-y01","d10-x01-y03"]
analyses['4Pi']["BESII_2007_I750713" ] = ["d01-x01-y03"]
analyses['4Pi']["SND_2001_I579319" ] = ["d01-x01-y01","d02-x01-y01"]
analyses['4Pi']["DM1_1982_I168552" ] = ["d01-x01-y01"]
analyses['4Pi']["DM1_1979_I132828" ] = ["d01-x01-y01"]
analyses['4Pi']["GAMMAGAMMA_1980_I153382"] = ["d01-x01-y01"]
analyses['4Pi']["GAMMAGAMMA_1981_I158474"] = ["d01-x01-y02"]
analyses["4Pi"]["BESIII_2020_I1817739" ] = ["d02-x01-y01"]
analyses["4Pi"]["BESIII_2021_I1929314" ] = ["d01-x01-y03"]
# (these are Omega(-> pi0 gamma) pi0)
analyses["OmegaPi"]["CMD2_2003_I616446" ] = ["d01-x01-y01"]
analyses["OmegaPi"]["SND_2000_I503946" ] = ["d01-x01-y01"]
analyses["OmegaPi"]["SND_2000_I527752" ] = ["d01-x01-y01"]
analyses["OmegaPi"]["SND_2016_I1489182" ] = ["d01-x01-y01"]
# non Omega
analyses["OmegaPi"]["SND_2002_I587084" ] = ["d01-x01-y01"]
analyses["OmegaPi"]["CMD2_2004_I630009" ] = ["d01-x01-y01"]
analyses["OmegaPi"]["KLOE_2008_I791841" ] = ["d02-x01-y01"]
# from 4 Pion
analyses["OmegaPi"]["CMD2_1999_I483994" ] = ["d03-x01-y01"]
analyses['OmegaPi']["ND_1991_I321108" ] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01",
"d04-x01-y01","d10-x01-y03"]
analyses["OmegaPi"]["BESIII_2020_I1817739"] = ["d02-x01-y01"]
# omega 2 pi
analyses["OmegaPiPi"]["BABAR_2007_I758568" ] = ["d01-x01-y01","d03-x01-y01","d04-x01-y01"]
analyses["OmegaPiPi"]["BABAR_2018_I1700745" ] = ["d01-x01-y01","d03-x01-y01"]
analyses['OmegaPiPi']["BESIII_2021_I1999208"] = ["d01-x01-y01"]
analyses["OmegaPiPi"]["CMD2_2000_I532970" ] = ["d01-x01-y01"]
analyses["OmegaPiPi"]["DM1_1981_I166964" ] = ["d01-x01-y01"]
analyses["OmegaPiPi"]["DM2_1992_I339265" ] = ["d02-x01-y01"]
analyses['OmegaPiPi']["ND_1991_I321108" ] = ["d14-x01-y01"]
analyses['OmegaPiPi']["BESIII_2022_I2133889"] = ["d01-x01-y01","d02-x01-y01","d02-x01-y02","d02-x01-y03",
"d02-x01-y04","d02-x01-y05","d02-x01-y06"]
# 5 pion
analyses["5Pi"]["CMD2_2000_I532970" ] = ["d03-x01-y01"]
analyses["5Pi"]["BABAR_2007_I758568" ] = ["d01-x01-y01"]
analyses['5Pi']["ND_1991_I321108" ] = ["d14-x01-y01"]
analyses['5Pi']["GAMMAGAMMA_1981_I158474" ] = ["d01-x01-y03"]
analyses["5Pi"]["BABAR_2018_I1700745" ] = ["d01-x01-y01"]
analyses["5Pi"]["BESIII_2021_I1929314" ] = ["d01-x01-y07"]
# 2K 1 pi
analyses["2K1Pi"]["BABAR_2008_I765258" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["2K1Pi"]["BABAR_2017_I1511276" ] = ["d01-x01-y01"]
analyses["2K1Pi"]["BESII_2008_I801208" ] = ["d01-x01-y01"]
analyses["2K1Pi"]["BESIII_2018_I1691798"] = ["d01-x01-y01"]
analyses["2K1Pi"]["BESIII_2022_I2033007"] = ["d01-x01-y01","d03-x01-y01","d04-x01-y01"]
analyses["2K1Pi"]["DM1_1982_I176801" ] = ["d01-x01-y01"]
analyses["2K1Pi"]["DM2_1991_I318558" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["2K1Pi"]["SND_2018_I1637194" ] = ["d01-x01-y01"]
analyses["2K1Pi"]["SND_2020_I1806118" ] = ["d01-x01-y01"]
# phi pi
analyses["PhiPi"]["BABAR_2008_I765258" ] = ["d02-x01-y01","d03-x01-y01"]
analyses["PhiPi"]["BABAR_2017_I1511276" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["PhiPi"]["BESIII_2022_I2033007"] = ["d01-x01-y01","d02-x01-y01"]
analyses["PhiPi"]["SND_2020_I1806118" ] = ["d02-x01-y01"]
# 2K 2 pi
analyses["2K2Pi"]["BABAR_2005_I676691" ] = ["d02-x01-y01"]
analyses["2K2Pi"]["BABAR_2007_I747875" ] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01",
"d04-x01-y01","d05-x01-y01","d07-x01-y01"]
analyses["2K2Pi"]["BABAR_2012_I892684" ] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01",
"d04-x01-y01","d05-x01-y01",
"d06-x01-y01","d07-x01-y01"]
analyses["2K2Pi"]["BABAR_2014_I1287920" ] = ["d09-x01-y01","d10-x01-y01","d11-x01-y01"]
analyses["2K2Pi"]["BABAR_2017_I1511276" ] = ["d03-x01-y01","d04-x01-y01"]
analyses["2K2Pi"]["BABAR_2017_I1591716" ] = ["d01-x01-y01","d02-x01-y01"]
analyses['2K2Pi']["BESII_2007_I750713" ] = ["d01-x01-y04"]
analyses["2K2Pi"]["BESII_2008_I801210" ] = ["d01-x01-y02"]
analyses["2K2Pi"]["BESII_2008_I801208" ] = ["d01-x01-y02"]
analyses['2K2Pi']["BESIII_2018_I1699641"] = ["d01-x01-y01","d02-x01-y01"]
analyses['2K2Pi']["BESIII_2020_I1775344"] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01",
"d04-x01-y01","d05-x01-y01","d06-x01-y01"]
analyses['2K2Pi']["BESIII_2021_I1997451"] = ["d01-x01-y01"]
analyses['2K2Pi']["BESIII_2018_I1651451"] = ["d01-x01-y01","d01-x01-y02"]
analyses["2K2Pi"]["BELLE_2009_I809630" ] = ["d01-x01-y01"]
analyses["2K2Pi"]["CMD3_2016_I1395968" ] = ["d01-x01-y01"]
analyses['2K2Pi']["CMD3_2019_I1770428" ] = ["d01-x01-y06"]
analyses["2K2Pi"]["DM1_1982_I169382" ] = ["d01-x01-y01"]
analyses["2K2Pi"]["BESIII_2021_I1929314"] = ["d01-x01-y01"]
# 4K
analyses["4K"]["BESIII_2019_I1743841"] = ["d01-x01-y01","d02-x01-y01"]
analyses["4K"]["BESIII_2021_I1929314"] = ["d01-x01-y02"]
analyses["4K"]["BABAR_2005_I676691" ] = ["d03-x01-y01"]
analyses["4K"]["BABAR_2014_I1287920" ] = ["d12-x01-y01"]
analyses["4K"]["BABAR_2012_I892684" ] = ["d08-x01-y01"]
analyses["4K"]["BABAR_2007_I747875" ] = ["d07-x01-y01"]
analyses['4K']["BESII_2007_I750713" ] = ["d01-x01-y06","d01-x01-y07"]
# 6 mesons
analyses["6m"]["BESIII_2021_I1929314"] = ["d01-x01-y05","d01-x01-y06"]
-analyses["6m"]["CMD3_2013_I1217420" ] = ["d01-x01-y01"]
+analyses["6m"]["CMD3_2013_I1217420" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03"]
analyses["6m"]["SND_2019_I1726419" ] = ["d01-x01-y01","d01-x01-y04"]
analyses["6m"]["CMD3_2017_I1606078" ] = ["d01-x01-y03","d01-x01-y04"]
analyses["6m"]["CMD3_2019_I1720610" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03"]
analyses["6m"]["BABAR_2018_I1700745"] = ["d04-x01-y01","d05-x01-y01"]
analyses["6m"]["SND_2016_I1471515" ] = ["d01-x01-y06"]
analyses["6m"]["DM1_1981_I166353" ] = ["d01-x01-y01"]
analyses["6m"]["BABAR_2006_I709730" ] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01"]
analyses["6m"]["BABAR_2007_I758568" ] = ["d05-x01-y01","d07-x01-y01",
- "d08-x01-y01","d09-x01-y01","d10-x01-y01","d11-x01-y01"]
+ "d08-x01-y01","d09-x01-y01","d10-x01-y01","d11-x01-y01"]
analyses["6m"]["BESII_2007_I763880" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03","d01-x01-y04",
"d01-x01-y05","d01-x01-y06","d01-x01-y07"]
analyses["6m"]["BESII_2007_I762901" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03","d01-x01-y04",
"d01-x01-y06","d01-x01-y07","d01-x01-y08","d01-x01-y09","d01-x01-y10"]
analyses["6m"]["CLEO_2006_I691720" ] = ["d01-x01-y02","d01-x01-y03","d01-x01-y04","d01-x01-y05",
"d01-x01-y07","d01-x01-y08","d01-x01-y09","d01-x01-y10","d01-x01-y11",
"d01-x01-y12","d01-x01-y13","d01-x01-y14","d01-x01-y15","d01-x01-y17"]
analyses["6m"]["BESII_2008_I801210" ] = ["d01-x01-y03","d01-x01-y04","d01-x01-y05"]
analyses["6m"]["BESII_2008_I801208" ] = ["d01-x01-y03","d01-x01-y04","d01-x01-y05","d01-x01-y06"]
analyses["6m"]["MARKI_1982_I169326" ] = ["d06-x01-y01"]
analyses["6m"]["MARKI_1975_I100592" ] = ["d01-x01-y01","d02-x01-y01"]
analyses['6m']["BESII_2007_I750713" ] = ["d01-x01-y08","d01-x01-y09","d01-x01-y11",
- "d01-x01-y12","d01-x01-y13","d01-x01-y14",
+ "d01-x01-y12","d01-x01-y13","d01-x01-y14",
"d01-x01-y15","d01-x01-y16","d01-x01-y17","d01-x01-y18"]
analyses['6m']["SND_2016_I1473343" ] = ["d01-x01-y01"]
analyses['6m']["BESIII_2020_I1788734"] = ["d01-x01-y01"]
analyses['6m']["BABAR_2021_I1844422" ] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01",
"d04-x01-y01","d05-x01-y01","d06-x01-y01"]
analyses['6m']["BESIII_2020_I1837725" ] = ["d01-x01-y01"]
analyses["6m"]["BABAR_2021_I1938254"] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01","d04-x01-y01","d05-x01-y01"]
analyses["6m"]["CMD3_2022_I2108984"] = ["d01-x01-y01","d02-x01-y01","d02-x01-y02"]
analyses["6m"]["BABAR_2022_I2120528"] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01","d04-x01-y01","d05-x01-y01",
"d06-x01-y01","d07-x01-y01","d08-x01-y01","d09-x01-y01","d10-x01-y01"]
# other baryon processes
analyses['Baryon']["BESIII_2017_I1509241" ] = ["d01-x01-y01"]
analyses['Baryon']["BESIII_2021_I1845443" ] = ["d01-x01-y01","d02-x01-y01"]
analyses['Baryon']["BESIII_2021_I1859248" ] = ["d01-x01-y01"]
analyses["Baryon"]["BESIII_2021_I1929314" ] = ["d01-x01-y04","d01-x01-y08"]
analyses["Baryon"]["BESIII_2018_I1681638" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03"]
# DD
analyses["DD"]["BELLE_2007_I723333" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["DD"]["BELLE_2007_I756012" ] = ["d01-x01-y01"]
analyses["DD"]["BELLE_2007_I756643" ] = ["d01-x01-y01"]
analyses["DD"]["BELLE_2008_I757220" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["DD"]["BELLE_2008_I759073" ] = ["d01-x01-y01"]
analyses["DD"]["BELLE_2020_I1789775" ] = ["d01-x01-y01"]
analyses["DD"]["BELLE_2019_I1762826" ] = ["d01-x01-y01"]
analyses["DD"]["BABAR_2008_I776519" ] = ["d01-x01-y01","d01-x01-y02"]
analyses["DD"]["BELLE_2008_I791660" ] = ["d01-x01-y01"]
analyses["DD"]["BELLE_2013_I1225975" ] = ["d01-x01-y01"]
analyses["DD"]["BELLE_2014_I1282602" ] = ["d01-x01-y01"]
analyses["DD"]["BELLE_2015_I1324785" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2022_I1989527" ] = ["d01-x01-y03","d02-x01-y03"]
analyses["DD"]["BESIII_2021_I1933191" ] = ["d01-x01-y03"]
analyses["DD"]["BESIII_2016_I1457597" ] = ["d01-x01-y07"]
analyses["DD"]["BESIII_2015_I1355215" ] = ["d01-x01-y10"]
analyses["DD"]["BESIII_2015_I1377204" ] = ["d01-x01-y10"]
analyses["DD"]["BESIII_2016_I1495838" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["DD"]["CRYSTAL_BALL_1986_I238081"] = ["d02-x01-y01"]
analyses["DD"]["CLEOC_2008_I777917" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03",
"d02-x01-y01","d02-x01-y02","d02-x01-y03",
"d03-x01-y01","d03-x01-y02","d03-x01-y03",
"d04-x01-y01","d04-x01-y02",
"d05-x01-y01","d05-x01-y02"]
analyses["DD"]["BELLE_2017_I1613517" ] = ["d01-x01-y01","d01-x01-y02"]
analyses["DD"]["BESIII_2014_I1323621" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2015_I1406939" ] = ["d02-x01-y06","d03-x01-y06"]
analyses["DD"]["BESIII_2017_I1628093" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2019_I1723934" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2019_I1756876" ] = ["d01-x01-y09","d01-x01-y10"]
analyses["DD"]["BABAR_2007_I729388" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2015_I1329785" ] = ["d01-x01-y08","d02-x01-y08","d03-x01-y08"]
analyses["DD"]["BESIII_2017_I1494065" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["DD"]["BESIII_2017_I1596897" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2018_I1653121" ] = ["d01-x01-y01","d01-x01-y02"]
analyses["DD"]["BESIII_2020_I1762922" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2018_I1633425" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2018_I1685535" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["DD"]["BELLE_2011_I878228" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03"]
analyses["DD"]["BABAR_2010_I864027" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03"]
analyses["DD"]["BABAR_2009_I815035" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03","d02-x01-y01"]
analyses["DD"]["BES_1999_I508349" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03","d01-x01-y04"]
analyses["DD"]["BESIII_2020_I1795949" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["DD"]["BESIII_2021_I1867196" ] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01"]
analyses["DD"]["BESIII_2020_I1784442" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["DD"]["BESIII_2021_I1849633" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2021_I1880103" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["DD"]["BESIII_2022_I2129305" ] = ["d01-x01-y01","d02-x01-y01"]
analyses["DD"]["BESIII_2022_I2050468" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2021_I1826422" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2017_I1600581" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2022_I2097619" ] = ["d01-x01-y01"]
analyses["DD"]["BESIII_2022_I2068180" ] = ["d01-x01-y01"]
# BB
analyses["BB"]["BELLE_2008_I764099" ] = ["d01-x01-y01","d02-x01-y01",
"d03-x01-y01","d04-x01-y01"]
analyses["BB"]["BELLE_2016_I1389855" ] = ["d01-x01-y02","d01-x01-y03"]
analyses["BB"]["BELLE_2021_I1859137" ] = ["d01-x01-y01","d01-x01-y02","d01-x01-y03"]
analyses["BB"]["CLEO_1991_I29927" ] = ["d01-x01-y01"]
analyses["BB"]["CLEO_1999_I474676" ] = ["d01-x01-y01","d01-x01-y02"]
analyses["BB"]["CUSB_1991_I325661" ] = ["d01-x01-y01"]
# hyperons
analyses["LL"]["BABAR_2007_I760730" ] = ["d01-x01-y01","d02-x01-y01","d03-x01-y01"]
analyses["LL"]["BESIII_2018_I1627871"] = ["d01-x01-y01"]
analyses["LL"]["BESIII_2019_I1726357"] = ["d01-x01-y01"]
analyses["LL"]["BESIII_2019_I1758883"] = ["d01-x01-y05"]
analyses["LL"]["BESIII_2020_I1814783"] = ["d01-x01-y01","d01-x01-y02",
"d02-x01-y01","d02-x01-y02"]
analyses["LL"]["BESIII_2020_I1823448"] = ["d01-x01-y04"]
analyses["LL"]["BESIII_2021_I1866233"] = ["d01-x01-y01"]
analyses["LL"]["BESIII_2021_I1940960"] = ["d01-x01-y01"]
analyses["LL"]["BESIII_2021_I1900124"] = ["d01-x01-y01"]
analyses["LL"]["DM2_1990_I297706" ] = ["d02-x01-y01"]
# list the analysis if required and quit()
allProcesses=False
if "All" in opts.processes :
allProcesses=True
processes = sorted(list(analyses.keys()))
else :
processes = sorted(list(set(opts.processes)))
if(opts.list) :
for process in processes :
print (" ".join(analyses[process]))
quit()
if(opts.plot) :
output=""
for process in processes:
for analysis in analyses[process] :
if(analysis=="CMD3_2019_I1770428") :
for iy in range(1,3) :
output+= " -m/%s/%s" % (analysis,"d02-x01-y0%s"%iy)
elif(analysis=="BES_1999_I508349") :
for ix in range(2,4) :
for iy in range(1,3) :
output+= " -m/%s/%s" % (analysis,"d0%s-x01-y0%s"%(ix,iy))
elif(analysis=="BESIII_2019_I1726357") :
for ix in range(2,4) :
output+= " -m/%s/%s" % (analysis,"d0%s-x01-y01"% ix)
elif(analysis=="BESIII_2020_I1775344") :
for ix in range(1,6) :
output+= " -m/%s/%s" % (analysis,"d07-x01-y0%s"% ix)
output+= " -m/%s/%s" % (analysis,"d08-x01-y0%s"% ix)
elif(analysis=="BESIII_2020_I1814783") :
for ix in range(1,3) :
output+= " -m/%s/%s" % (analysis,"d03-x01-y0%s"% ix)
elif(analysis=="SND_2020_I1809286") :
for ix in range(1,5) :
output+= " -m/%s/%s" % (analysis,"d04-x01-y0%s"% ix)
for plot in analyses[process][analysis]:
output+= " -m/%s/%s" % (analysis,plot)
print (output)
quit()
# mapping of process to me to use
me = { "PiPi" : "MEee2Pions",
"KK" : "MEee2Kaons",
"3Pi" : "MEee3Pions",
"4Pi" : "MEee4Pions",
"EtaPiPi" : "MEee2EtaPiPi",
"EtaprimePiPi" : "MEee2EtaPrimePiPi",
"EtaPhi" : "MEee2EtaPhi",
"EtaOmega" : "MEee2EtaOmega",
"OmegaPi" : "MEee2OmegaPi",
"OmegaPiPi" : "MEee2OmegaPiPi",
"PhiPi" : "MEee2PhiPi",
"PiGamma" : "MEee2PiGamma",
"EtaGamma" : "MEee2EtaGamma",
"PPbar" : "MEee2PPbar",
"LL" : "MEee2LL" ,
"2K1Pi" : "MEee2KKPi" }
# get the particle masses from Herwig
particles = { "pi+" : 0., "pi0" : 0. ,"eta" : 0. ,"eta'" : 0. ,"phi" : 0. ,"omega" : 0. ,"p+" : 0. ,"K+" : 0.}
for val in particles :
tempTxt = "get /Herwig/Particles/%s:NominalMass\nget /Herwig/Particles/%s:WidthLoCut\n" % (val,val)
with open("temp.in",'w') as f:
f.write(tempTxt)
p = subprocess.Popen(["../src/Herwig", "read","temp.in"],stdout=subprocess.PIPE)
vals = p.communicate()[0].split()
mass = float(vals[0])-float(vals[1])
particles[val]=mass
os.remove("temp.in")
# minimum CMS energies for specific processes
minMass = { "PiPi" : 2.*particles["pi+"],
"KK" : 2.*particles["K+"],
"3Pi" : 2.*particles["pi+"]+particles["pi0"],
"4Pi" : 2.*particles["pi+"]+2.*particles["pi0"],
"EtaPiPi" : particles["eta"]+2.*particles["pi+"],
"EtaprimePiPi" : particles["eta'"]+2.*particles["pi+"],
"EtaPhi" : particles["phi"]+particles["eta"],
"EtaOmega" : particles["omega"]+particles["eta"],
"OmegaPi" : particles["omega"]+particles["pi0"],
"OmegaPiPi" : particles["omega"]+2.*particles["pi0"],
"PhiPi" : particles["phi"]+particles["pi0"],
"PiGamma" : particles["pi0"],
"EtaGamma" : particles["eta"],
"PPbar" : 2.*particles["p+"],
"LL" : 0.,
"2K1Pi" : 2.*particles["K+"]+particles["pi0"] }
# energies we need
energies={}
def nearestEnergy(en) :
Emin=0
delta=1e30
anals=[]
for val in energies :
if(abs(val-en)<delta) :
delta = abs(val-en)
Emin = val
anals=energies[val]
return (Emin,delta,anals)
for process in processes:
if(process not in analyses) : continue
matrix=""
if( process in me ) :
matrix = me[process]
for analysis in analyses[process] :
aos=yoda.read(os.path.join(os.path.join(os.getcwd(),path),analysis+".yoda"))
if(len(aos)==0) : continue
for plot in analyses[process][analysis] :
histo = aos["/REF/%s/%s" %(analysis,plot)]
for point in histo.points() :
energy = point.x()
if(analysis=="KLOE_2009_I797438" or
analysis=="KLOE_2005_I655225" or
analysis=="KLOE2_2017_I1634981" or
analysis=="FENICE_1994_I377833") :
energy = math.sqrt(energy)
if(energy>200) :
energy *= 0.001
emin,delta,anals = nearestEnergy(energy)
if(energy in energies) :
if(analysis not in energies[energy][1]) :
energies[energy][1].append(analysis)
if(matrix!="" and matrix not in energies[energy][0] and
minMass[process]<=energy) :
energies[energy][0].append(matrix)
elif(delta<1e-7) :
if(analysis not in anals[1]) :
anals[1].append(analysis)
if(matrix!="" and matrix not in anals[0] and
minMass[process]<=energy) :
anals[0].append(matrix)
else :
if(matrix=="") :
energies[energy]=[[],[analysis]]
elif(minMass[process]<=energy) :
energies[energy]=[[matrix],[analysis]]
with open("python/LowEnergy-EE-Perturbative.in", 'r') as f:
templateText = f.read()
perturbative=Template( templateText )
with open("python/LowEnergy-EE-NonPerturbative.in", 'r') as f:
templateText = f.read()
nonPerturbative=Template( templateText )
targets=""
for energy in sorted(energies) :
anal=""
for analysis in energies[energy][1]:
anal+= "insert /Herwig/Analysis/Rivet:Analyses 0 %s\n" %analysis
proc=""
matrices = energies[energy][0]
if(allProcesses) : matrices = me.values()
for matrix in matrices:
proc+="insert SubProcess:MatrixElements 0 %s\n" % matrix
proc+="set %s:Flavour %s\n" % (matrix,opts.flavour)
maxflavour =5
if(energy<thresholds[1]) :
maxflavour=2
elif(energy<thresholds[2]) :
maxflavour=3
elif(energy<thresholds[3]) :
maxflavour=4
# input file for perturbative QCD
if(opts.perturbative and energy> thresholds[0]) :
inputPerturbative = perturbative.substitute({"ECMS" : "%8.6f" % energy, "ANALYSES" : anal,
"lepton" : "", "maxflavour" : maxflavour, 'name' : "EE"})
with open(opts.dest+"/Rivet-LowEnergy-EE-Perturbative-%8.6f.in" % energy ,'w') as f:
f.write(inputPerturbative)
targets += "Rivet-LowEnergy-EE-Perturbative-%8.6f.yoda " % energy
# input file for currents
if(opts.nonPerturbative and proc!="") :
inputNonPerturbative = nonPerturbative.substitute({"ECMS" : "%8.6f" % energy, "ANALYSES" : anal,
"processes" : proc, 'name' : "EE"})
with open(opts.dest+"/Rivet-LowEnergy-EE-NonPerturbative-%8.6f.in" % energy ,'w') as f:
f.write(inputNonPerturbative)
targets += "Rivet-LowEnergy-EE-NonPerturbative-%8.6f.yoda " % energy
print (targets)
diff --git a/Tests/python/make_input_files.py.in b/Tests/python/make_input_files.py.in
--- a/Tests/python/make_input_files.py.in
+++ b/Tests/python/make_input_files.py.in
@@ -1,1589 +1,1588 @@
#! @PYTHON@
+# -*- mode: python -*-
from __future__ import print_function
import logging,sys,os
from string import Template
from HerwigInputs import *
import sys
if sys.version_info[:3] < (2,4,0):
print ("rivet scripts require Python version >= 2.4.0... exiting")
sys.exit(1)
if __name__ == "__main__":
import logging
from optparse import OptionParser, OptionGroup
parser = OptionParser(usage="%prog name [...]")
simulation=""
numberOfAddedProcesses=0
def addProcess(thefactory,theProcess,Oas,Oew,scale,mergedlegs,NLOprocesses):
global numberOfAddedProcesses
global simulation
numberOfAddedProcesses+=1
res ="set "+thefactory+":OrderInAlphaS "+Oas+"\n"
res+="set "+thefactory+":OrderInAlphaEW "+Oew+"\n"
res+="do "+thefactory+":Process "+theProcess+" "
if ( mergedlegs != 0 ):
if simulation!="Merging":
print ("simulation is not Merging, trying to add merged legs.")
sys.exit(1)
res+="["
for j in range(mergedlegs):
res+=" j "
res+="]"
res+="\n"
if (NLOprocesses!=0):
if simulation!="Merging":
print ("simulation is not Merging, trying to add NLOProcesses.")
sys.exit(1)
res+="set MergingFactory:NLOProcesses %s \n" % NLOprocesses
if ( scale != "" ):
res+="set "+thefactory+":ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/"+scale+"\n"
return res
addedBRReweighter=False
def addBRReweighter():
global addedBRReweighter
if(addedBRReweighter):
logging.error("Can only add BRReweighter once.")
sys.exit(1)
res="create Herwig::BranchingRatioReweighter /Herwig/Generators/BRReweighter\n"
res+="insert /Herwig/Generators/EventGenerator:EventHandler:PostHadronizationHandlers 0 /Herwig/Generators/BRReweighter\n"
addedBRReweighter=True
return res
selecteddecaymode=False
def selectDecayMode(particle,decaymodes):
global selecteddecaymode
res="do /Herwig/Particles/"+particle+":SelectDecayModes"
for decay in decaymodes:
res+=" /Herwig/Particles/"+particle+"/"+decay
res+="\n"
selecteddecaymode=True
return res
ME_Upsilon = """\
create Herwig::MEee2VectorMeson /Herwig/MatrixElements/MEUpsilon HwMELepton.so
set /Herwig/MatrixElements/MEUpsilon:VectorMeson /Herwig/Particles/Upsilon(4S)
set /Herwig/MatrixElements/MEUpsilon:Coupling 96.72794
""" + insert_ME("MEUpsilon")
-
(opts, args) = parser.parse_args()
## Check args
if len(args) != 1:
logging.error("Must specify at least input file")
sys.exit(1)
name = args[0]
print (name)
# work out name and type of the collider
(collider,have_hadronic_collider) = identifyCollider(name)
thefactory="Factory"
# workout the type of simulation
(simulation,templateName,parameterName,parameters)=identifySimulation(name,collider,have_hadronic_collider)
# set theFactory for merging
if simulation=="Merging":
thefactory="MergingFactory"
# settings for four flavour scheme
fourFlavour="""
read Matchbox/FourFlavourScheme.in
{bjetgroup}
set /Herwig/Cuts/MatchboxJetMatcher:Group bjet
""".format(bjetgroup=particlegroup(thefactory,'bjet','b','bbar','c', 'cbar',
's','sbar','d','dbar','u','ubar','g'))
# work out the process and parameters
process=StringBuilder()
# DIS
if(collider=="DIS") :
if(simulation=="") :
if "NoME" in name :
process = StringBuilder("set /Herwig/Shower/ShowerHandler:HardEmission None")
parameterName=parameterName.replace("NoME-","")
parameterName=parameterName.replace("DIS-" ,"")
if "CC" in parameterName :
process += insert_ME("MEDISCC")
else :
process += insert_ME("MEDISNC")
elif(simulation=="Powheg") :
if "CC" in parameterName :
process = StringBuilder(insert_ME("PowhegMEDISCC"))
else :
process = StringBuilder(insert_ME("PowhegMEDISNC"))
elif(simulation=="Matchbox" ) :
if "CC" in name :
if "e-" in parameterName :
process = StringBuilder(addProcess(thefactory,"e- p -> nu_e j","0","2","",0,0))
else :
process = StringBuilder(addProcess(thefactory,"e+ p -> nu_ebar j","0","2","",0,0))
else :
if "e-" in parameterName :
process = StringBuilder(addProcess(thefactory,"e- p -> e- j","0","2","",0,0))
else :
process = StringBuilder(addProcess(thefactory,"e+ p -> e+ j","0","2","",0,0))
elif(simulation=="Merging" ) :
if "CC" in name :
if "e-" in parameterName :
process = StringBuilder(addProcess(thefactory,"e- p -> e- j","0","2","",2,2))
else :
process = StringBuilder(addProcess(thefactory,"e+ p -> e+ j","0","2","",2,2))
else :
if "e-" in parameterName :
process = StringBuilder(addProcess(thefactory,"e- p -> nu_e j","0","2","",2,2))
else :
process = StringBuilder(addProcess(thefactory,"e+ p -> nu_ebar j","0","2","",2,2))
Q2Min=1.
Q2Max=1000000.
if "VeryLow" in name :
Q2Max=20.
parameterName=parameterName.replace("-VeryLowQ2","")
elif "Low" in name :
Q2Min=20.
Q2Max=100.
parameterName=parameterName.replace("-LowQ2","")
elif "Med" in name :
Q2Min=100.
Q2Max=1000.
parameterName=parameterName.replace("-MedQ2","")
elif "High" in name :
Q2Min=1000.
parameterName=parameterName.replace("-HighQ2","")
if "CC" in name :
process+="set /Herwig/Cuts/ChargedCurrentCut:MaxQ2 2%s\nset /Herwig/Cuts/ChargedCurrentCut:MinQ2 %s\n" %(Q2Max,Q2Min)
else :
process+="set /Herwig/Cuts/NeutralCurrentCut:MaxQ2 2%s\nset /Herwig/Cuts/NeutralCurrentCut:MinQ2 %s\n" %(Q2Max,Q2Min)
# EE
elif(collider=="EE") :
if(simulation=="") :
if "gg" in parameterName :
process = StringBuilder("create Herwig::MEee2Higgs2SM /Herwig/MatrixElements/MEee2Higgs2SM\n")
process+=insert_ME("MEee2Higgs2SM","Gluon","Allowed")
elif "LL" in parameterName :
process = StringBuilder(insert_ME("MEee2gZ2ll"))
process += "set /Herwig/MatrixElements/MEee2gZ2ll:Allowed Charged\n"
elif "WW" in parameterName :
process = StringBuilder(insert_ME("MEee2VV"))
process += "set /Herwig/MatrixElements/MEee2VV:Process WW\n"
else :
process = StringBuilder(insert_ME("MEee2gZ2qq"))
try :
ecms = float(parameterName)
if(ecms<=3.75) :
process+= "set /Herwig/MatrixElements/MEee2gZ2qq:MaximumFlavour 3\n"
elif(ecms<=10.6) :
process+= "set /Herwig/MatrixElements/MEee2gZ2qq:MaximumFlavour 4\n"
except :
pass
elif(simulation=="Powheg") :
if "LL" in parameterName :
process = StringBuilder(insert_ME("PowhegMEee2gZ2ll"))
process += "set /Herwig/MatrixElements/PowhegMEee2gZ2ll:Allowed Charged\n"
else :
process = StringBuilder(insert_ME("PowhegMEee2gZ2qq"))
try :
ecms = float(parameterName)
if(ecms<=3.75) :
process+= "set /Herwig/MatrixElements/PowhegMEee2gZ2qq:MaximumFlavour 3\n"
elif(ecms<=10.6) :
process+= "set /Herwig/MatrixElements/PowhegMEee2gZ2qq:MaximumFlavour 4\n"
except :
pass
elif(simulation=="Matchbox" ) :
try :
ecms = float(parameterName)
if(ecms<=3.75) :
process = StringBuilder(addProcess(thefactory,"e- e+ -> u ubar","0","2","",0,0))
process+=addProcess(thefactory,"e- e+ -> d dbar","0","2","",0,0)
process+=addProcess(thefactory,"e- e+ -> s sbar","0","2","",0,0)
elif(ecms<=10.6) :
process = StringBuilder(addProcess(thefactory,"e- e+ -> u ubar","0","2","",0,0))
process+=addProcess(thefactory,"e- e+ -> d dbar","0","2","",0,0)
process+=addProcess(thefactory,"e- e+ -> c cbar","0","2","",0,0)
process+=addProcess(thefactory,"e- e+ -> s sbar","0","2","",0,0)
else :
process = StringBuilder(addProcess(thefactory,"e- e+ -> j j","0","2","",0,0))
except:
process = StringBuilder(addProcess(thefactory,"e- e+ -> j j","0","2","",0,0))
elif(simulation=="Merging" ) :
try :
ecms = float(parameterName)
if(ecms<=10.1) :
process = StringBuilder(addProcess(thefactory,"e- e+ -> j j","0","2","",2,2))
process+="read Matchbox/FourFlavourScheme.in"
else :
process = StringBuilder(addProcess(thefactory,"e- e+ -> j j","0","2","",2,2))
except:
process = StringBuilder(addProcess(thefactory,"e- e+ -> j j","0","2","",2,2))
# EE-Gamma
elif(collider=="EE-Gamma") :
if(simulation=="") :
if("mumu" in parameterName) :
process = StringBuilder(insert_ME("MEgg2ff","Muon"))
process +="set /Herwig/Cuts/Cuts:MHatMin 3.\n"
elif( "tautau" in parameterName) :
process = StringBuilder(insert_ME("MEgg2ff","Tau"))
process +="set /Herwig/Cuts/Cuts:MHatMin 3.\n"
elif( "Jets" in parameterName) :
if("Direct" in parameterName ) :
process = StringBuilder(insert_ME("MEgg2ff","Quarks"))
elif("Single-Resolved" in parameterName ) :
process = StringBuilder(insert_ME("MEGammaP2Jets",None,"Process","SubProcess"))
process+= insert_ME("MEGammaP2Jets",None,"Process","SubProcess2")
else :
process = StringBuilder(insert_ME("MEQCD2to2"))
process+="insert /Herwig/Cuts/Cuts:OneCuts[0] /Herwig/Cuts/JetKtCut"
process+="set /Herwig/Cuts/JetKtCut:MinKT 3."
else :
print ("process not supported for Gamma Gamma processes at EE")
quit()
else :
print ("Only internal matrix elements currently supported for Gamma Gamma processes at EE")
quit()
elif(collider=="GammaGamma") :
if(simulation=="") :
if("mumu" in parameterName) :
process = StringBuilder(insert_ME("MEgg2ff"))
process +="set /Herwig/MatrixElements/MEgg2ff:Process Muon\n"
process +="set /Herwig/Cuts/Cuts:MHatMin 3.\n"
else :
print ("process not supported for Gamma Gamma processes at EE")
quit()
else :
print ("Only internal matrix elements currently supported for Gamma Gamma processes at EE")
quit()
# TVT
elif(collider=="TVT") :
process = StringBuilder("set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/pbar-\n")
ecms=1960.
if "Run-II" in parameterName : ecms = 1960.0
elif "Run-I" in parameterName : ecms = 1800.0
elif "900" in parameterName : ecms = 900.0
elif "630" in parameterName : ecms = 630.0
elif "300" in parameterName : ecms = 300.0
process+=collider_lumi(ecms)
if(simulation=="") :
if "PromptPhoton" in parameterName :
process+=insert_ME("MEGammaJet")
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 15.\n"
elif "DiPhoton-GammaGamma" in parameterName :
process+=insert_ME("MEGammaGamma")
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
parameterName=parameterName.replace("-GammaGamma","")
elif "DiPhoton-GammaJet" in parameterName :
process+=insert_ME("MEGammaJet")
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
parameterName=parameterName.replace("-GammaJet","")
elif "UE" in parameterName :
if "Dipole" in parameters["shower"]:
process+="read snippets/MB-DipoleShower.in\n"
else:
process+="read snippets/MB.in\n"
process+="read snippets/Diffraction.in\n"
process += "set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n"
process += "set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n"
elif "Jets" in parameterName :
process+=insert_ME("MEQCD2to2")
process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
if "DiJets" in name :
process +=jet_kt_cut( 30.)
cuts=[100.,300.,600.,900.,ecms]
for i in range(1,len(cuts)) :
tstring = "-DiJets-%s"%i
if tstring in parameterName :
process+=mhat_cut(cuts[i-1],cuts[i])
parameterName=parameterName.replace(tstring,"-DiJets")
else :
if "Run" in parameterName :
cuts=[5.,20.,40.,80.,160.,320.]
elif "300" in parameterName :
cuts=[5.,]
elif "630" in parameterName :
cuts=[5.,20.,40.]
elif "900" in parameterName :
cuts=[5.,]
cuts.append(ecms)
for i in range(1,len(cuts)) :
tstring = "-Jets-%s"%i
if tstring in parameterName :
process+=jet_kt_cut(cuts[i-1],cuts[i])
parameterName=parameterName.replace(tstring,"-Jets")
elif "Run-I-WZ" in parameterName :
process+=insert_ME("MEqq2W2ff","Electron")
process+=insert_ME("MEqq2gZ2ff","Electron")
elif "Run-II-W" in parameterName or "Run-I-W" in parameterName :
process+=insert_ME("MEqq2W2ff","Electron")
elif "Run-II-Z-e" in parameterName or "Run-I-Z" in parameterName :
process +=insert_ME("MEqq2gZ2ff","Electron")
elif "Run-II-Z-LowMass-mu" in parameterName :
process +=insert_ME("MEqq2gZ2ff","Muon")
process+=addLeptonPairCut("25","70")
elif "Run-II-Z-HighMass-mu" in parameterName :
process +=insert_ME("MEqq2gZ2ff","Muon")
process+=addLeptonPairCut("150","600")
elif "Run-II-Z-mu" in parameterName :
process +=insert_ME("MEqq2gZ2ff","Muon")
elif(simulation=="Powheg") :
if "Run-I-WZ" in parameterName :
process+=insert_ME("PowhegMEqq2W2ff","Electron")
process+=insert_ME("PowhegMEqq2gZ2ff","Electron")
elif "Run-II-W" in parameterName or "Run-I-W" in parameterName :
process+=insert_ME("PowhegMEqq2W2ff","Electron")
elif "Run-II-Z-e" in parameterName or "Run-I-Z" in parameterName :
process+=insert_ME("PowhegMEqq2gZ2ff","Electron")
elif "Run-II-Z-LowMass-mu" in parameterName :
process+=insert_ME("PowhegMEqq2gZ2ff","Muon")
process+=addLeptonPairCut("25","70")
elif "Run-II-Z-HighMass-mu" in parameterName :
process+=insert_ME("PowhegMEqq2gZ2ff","Muon")
process+=addLeptonPairCut("150","600")
elif "Run-II-Z-mu" in parameterName :
process+=insert_ME("PowhegMEqq2gZ2ff","Muon")
elif "DiPhoton-GammaGamma" in parameterName :
process+=insert_ME("MEGammaGammaPowheg","GammaGamma")
process+=insert_ME("MEGammaGamma","gg")
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
process+=jet_kt_cut(5.)
parameterName=parameterName.replace("-GammaGamma","")
elif "DiPhoton-GammaJet" in parameterName :
process+=insert_ME("MEGammaGammaPowheg","VJet")
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
process+=jet_kt_cut(5.)
parameterName=parameterName.replace("-GammaJet","")
elif(simulation=="Matchbox" or simulation=="Merging" ) :
if "Jets" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p -> j j","2","0","MaxJetPtScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p -> j j","2","0","MaxJetPtScale",1,0)
if "DiJets" in parameterName :
process+=addFirstJet("30")+addSecondJet("25")
cuts=[100.,300.,600.,900.,ecms]
for i in range(1,len(cuts)) :
tstring = "-DiJets-%s"%i
if tstring in parameterName :
process+=addJetPairCut(cuts[i-1],cuts[i])
parameterName=parameterName.replace(tstring,"-DiJets")
else :
if "Run" in parameterName :
cuts=[5.,20.,40.,80.,160.,320.]
elif "300" in parameterName :
cuts=[5.,]
elif "630" in parameterName :
cuts=[5.,20.,40.]
elif "900" in parameterName :
cuts=[5.,]
cuts.append(ecms)
for i in range(1,len(cuts)) :
tstring = "-Jets-%s"%i
if tstring in parameterName :
process+=addFirstJet(cuts[i-1],cuts[i])
parameterName=parameterName.replace(tstring,"-Jets")
elif "Run-I-WZ" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p pbar e+ e-","0","2","LeptonPairMassScale",0,0)
process+=addProcess(thefactory,"p pbar e+ nu","0","2","LeptonPairMassScale",0,0)
process+=addProcess(thefactory,"p pbar e- nu","0","2","LeptonPairMassScale",0,0)
elif(simulation=="Merging"):
process+=particlegroup(thefactory,'epm','e+','e-')
process+=particlegroup(thefactory,'epmnu','e+','e-','nu_e','nu_ebar')
process+=addProcess(thefactory,"p pbar epm epmnu","0","2","LeptonPairMassScale",2,2)
process+=addLeptonPairCut("60","120")
elif "Run-II-W" in parameterName or "Run-I-W" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p pbar e+ nu","0","2","LeptonPairMassScale",0,0)
process+=addProcess(thefactory,"p pbar e- nu","0","2","LeptonPairMassScale",0,0)
elif(simulation=="Merging"):
process+=particlegroup(thefactory,'epm','e+','e-')
process+=addProcess(thefactory,"p pbar epm nu","0","2","LeptonPairMassScale",2,2)
process+=addLeptonPairCut("60","120")
elif "Run-II-Z-e" in parameterName or "Run-I-Z" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p pbar e+ e-","0","2","LeptonPairMassScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p pbar e+ e-","0","2","LeptonPairMassScale",2,2)
process+=addLeptonPairCut("60","120")
elif "Run-II-Z-LowMass-mu" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",2,2)
process+=addLeptonPairCut("25","70")
elif "Run-II-Z-HighMass-mu" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",2,2)
process+=addLeptonPairCut("150","600")
elif "Run-II-Z-mu" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p pbar mu+ mu-","0","2","LeptonPairMassScale",2,2)
process+=addLeptonPairCut("60","120")
# Star
elif(collider=="Star" ) :
process = StringBuilder("set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n")
process+= "set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n"
process+= "set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/p+\n"
process+= collider_lumi(200.0)
process+= "set /Herwig/Cuts/Cuts:X2Min 0.01\n"
if(simulation=="") :
if "UE" in parameterName :
if "Dipole" in parameters["shower"]:
process+="read snippets/MB-DipoleShower.in\n"
else:
process+="read snippets/MB.in\n"
process+="read snippets/Diffraction.in\n"
else :
process+=insert_ME("MEQCD2to2")
process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
if "Jets-1" in parameterName : process+=jet_kt_cut(2.)
elif "Jets-2" in parameterName : process+=jet_kt_cut(5.)
elif "Jets-3" in parameterName : process+=jet_kt_cut(20.)
elif "Jets-4" in parameterName : process+=jet_kt_cut(25.)
else :
logging.error("Star not supported for %s " % simulation)
sys.exit(1)
# ISR and SppS
elif ( collider=="ISR" or collider =="SppS" or collider == "SPS" or collider == "Fermilab" ) :
process = StringBuilder("set /Herwig/Decays/DecayHandler:LifeTimeOption 0\n")
process+="set /Herwig/Decays/DecayHandler:MaxLifeTime 10*mm\n"
if(collider=="SppS") :
process = StringBuilder("set /Herwig/Generators/EventGenerator:EventHandler:BeamB /Herwig/Particles/pbar-\n")
if "17.4" in parameterName : process+=collider_lumi( 17.4)
elif "27.4" in parameterName : process+=collider_lumi( 27.4)
elif "30" in parameterName : process+=collider_lumi( 30.4)
elif "38.8" in parameterName : process+=collider_lumi( 38.8)
elif "44" in parameterName : process+=collider_lumi( 44.4)
elif "53" in parameterName : process+=collider_lumi( 53.0)
elif "62" in parameterName : process+=collider_lumi( 62.2)
elif "63" in parameterName : process+=collider_lumi( 63.0)
elif "200" in parameterName : process+=collider_lumi(200.0)
elif "500" in parameterName : process+=collider_lumi(500.0)
elif "546" in parameterName : process+=collider_lumi(546.0)
elif "900" in parameterName : process+=collider_lumi(900.0)
if "UE" in parameterName :
if(simulation=="") :
if "Dipole" in parameters["shower"]:
process+="read snippets/MB-DipoleShower.in\n"
else:
process+="read snippets/MB.in\n"
process+="read snippets/Diffraction.in\n"
else :
logging.error(" SppS and ISR not supported for %s " % simulation)
sys.exit(1)
elif "Z-mu" in parameterName :
if simulation == "" :
process+=insert_ME("MEqq2gZ2ff","Muon")
process+=mhat_minm_maxm(2,2,20)
elif simulation == "Powheg" :
process+=insert_ME("PowhegMEqq2gZ2ff","Muon")
process+=mhat_minm_maxm(2,2,20)
elif(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",0,0)
process+=addLeptonPairCut("2","20")
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",2,2)
process+=addLeptonPairCut("2","20")
else :
logging.error(" SppS and ISR not supported for %s " % simulation)
sys.exit(1)
else :
logging.error(" Process not supported for SppS and ISR %s " % parameterName )
sys.exit(1)
# LHC
elif(collider=="LHC") :
ecms=7000.0
if parameterName.startswith("7-") : ecms = 7000.0
elif parameterName.startswith("8-") : ecms = 8000.0
elif parameterName.startswith("13-") : ecms = 13000.0
elif parameterName.startswith("900") : ecms = 900.0
elif parameterName.startswith("2360") : ecms = 2360.0
elif parameterName.startswith("2760") : ecms = 2760.0
elif parameterName.startswith("5-") : ecms = 5000.0
else : ecms = 7000.0
process = StringBuilder(collider_lumi(ecms))
if(simulation=="") :
if "VBF" in parameterName :
process+=insert_ME("MEPP2HiggsVBF")
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
addedBRReweighter = True
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
addedBRReweighter = True
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
addedBRReweighter = True
elif "8-" not in parameterName :
process+=selectDecayMode("h0",["h0->tau-,tau+;"])
addedBRReweighter = True
process+="set /Herwig/Particles/tau-:Stable Stable\n"
elif "ggHJet" in parameterName :
process+=selectDecayMode("h0",["h0->tau-,tau+;"])
addedBRReweighter = True
process+="set /Herwig/Particles/tau-:Stable Stable\n"
process+=insert_ME("MEHiggsJet")
process+=jet_kt_cut(20.)
elif "ggH" in parameterName :
process+=insert_ME("MEHiggs")
process+=insert_ME("MEHiggsJet","qqbar")
process+=jet_kt_cut(0.0)
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
addedBRReweighter = True
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
addedBRReweighter = True
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
addedBRReweighter = True
elif "8-" not in parameterName :
process+=selectDecayMode("h0",["h0->tau-,tau+;"])
addedBRReweighter = True
process+="set /Herwig/Particles/tau-:Stable Stable\n"
elif "PromptPhoton" in parameterName :
process+=insert_ME("MEGammaJet")
if "PromptPhoton-1" in parameterName :
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
process+="set /Herwig/Cuts/PhotonKtCut:MaxKT 25.\n"
parameterName=parameterName.replace("-1","")
elif "PromptPhoton-2" in parameterName :
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 25.\n"
process+="set /Herwig/Cuts/PhotonKtCut:MaxKT 80.\n"
parameterName=parameterName.replace("-2","")
elif "PromptPhoton-3" in parameterName :
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 80.\n"
process+="set /Herwig/Cuts/PhotonKtCut:MaxKT 150.\n"
parameterName=parameterName.replace("-3","")
elif "PromptPhoton-4" in parameterName :
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 150.\n"
process+="set /Herwig/Cuts/PhotonKtCut:MaxKT 500.\n"
parameterName=parameterName.replace("-4","")
elif "PromptPhoton-5" in parameterName :
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 500.\n"
parameterName=parameterName.replace("-5","")
elif "DiPhoton-GammaGamma" in parameterName :
process+=insert_ME("MEGammaGamma")
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
parameterName=parameterName.replace("-GammaGamma","")
elif "DiPhoton-GammaJet" in parameterName :
process+=insert_ME("MEGammaJet")
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
parameterName=parameterName.replace("-GammaJet","")
elif "8-WH" in parameterName :
process+=insert_ME("MEPP2WH")
process+=jet_kt_cut(0.0)
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
addedBRReweighter = True
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
addedBRReweighter = True
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
addedBRReweighter = True
elif "8-ZH" in parameterName :
process+=insert_ME("MEPP2ZH")
process+=jet_kt_cut(0.0)
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
addedBRReweighter = True
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
addedBRReweighter = True
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
addedBRReweighter = True
elif "WH" in parameterName :
process+=selectDecayMode("h0",["h0->b,bbar;"])
process+=selectDecayMode("W+",["W+->nu_e,e+;",
"W+->nu_mu,mu+;"])
addedBRReweighter = True
process+=insert_ME("MEPP2WH")
process+=jet_kt_cut(0.0)
elif "ZH" in parameterName :
process+=selectDecayMode("h0",["h0->b,bbar;"])
process+=selectDecayMode("Z0",["Z0->e-,e+;",
"Z0->mu-,mu+;"])
addedBRReweighter = True
process+=insert_ME("MEPP2ZH")
process+=jet_kt_cut(0.0)
elif "UE" in parameterName or "Cent" in parameterName :
if "Dipole" in parameters["shower"]:
process+="read snippets/MB-DipoleShower.in\n"
else:
process+="set /Herwig/Shower/ShowerHandler:IntrinsicPtGaussian 2.2*GeV\n"
process+="read snippets/MB.in\n"
process+="read snippets/Diffraction.in\n"
if "Long" in parameterName :
process += "set /Herwig/Decays/DecayHandler:MaxLifeTime 100*mm\n"
elif "8-DiJets" in parameterName or "7-DiJets" in parameterName or "13-DiJets" in parameterName :
process+=insert_ME("MEQCD2to2")
process+="set MEQCD2to2:MaximumFlavour 5\n"
process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
if "13-DiJets" not in parameterName :
if "-A" in parameterName :
process+=jet_kt_cut(45.)
process+="set /Herwig/Cuts/JetKtCut:MinEta -3.\n"
process+="set /Herwig/Cuts/JetKtCut:MaxEta 3.\n"
elif "-B" in parameterName :
process+=jet_kt_cut(20.)
process+="set /Herwig/Cuts/JetKtCut:MinEta -2.7\n"
process+="set /Herwig/Cuts/JetKtCut:MaxEta 2.7\n"
elif "-C" in parameterName :
process+=jet_kt_cut(20.)
process+="set /Herwig/Cuts/JetKtCut:MinEta -4.8\n"
process+="set /Herwig/Cuts/JetKtCut:MaxEta 4.8\n"
else :
if "-A" in parameterName :
process+=jet_kt_cut(60.)
process+="set /Herwig/Cuts/JetKtCut:MinEta -3.\n"
process+="set /Herwig/Cuts/JetKtCut:MaxEta 3.\n"
elif "-B" in parameterName :
process+=jet_kt_cut(180.)
process+="set /Herwig/Cuts/JetKtCut:MinEta -3.\n"
process+="set /Herwig/Cuts/JetKtCut:MaxEta 3.\n"
if "DiJets-1" in parameterName : process+=mhat_cut(90.)
elif "DiJets-2" in parameterName : process+=mhat_cut(200.)
elif "DiJets-3" in parameterName : process+=mhat_cut(450.)
elif "DiJets-4" in parameterName : process+=mhat_cut(750.)
elif "DiJets-5" in parameterName : process+=mhat_cut(950.)
elif "DiJets-6" in parameterName : process+=mhat_cut(1550.)
elif "DiJets-7" in parameterName : process+=mhat_cut(2150.)
elif "DiJets-8" in parameterName : process+=mhat_cut(2750.)
elif "DiJets-9" in parameterName : process+=mhat_cut(3750.)
elif "DiJets-10" in parameterName : process+=mhat_cut(4750.)
elif "DiJets-11" in parameterName : process+=mhat_cut(5750.)
elif( "7-Jets" in parameterName
or "8-Jets" in parameterName
or "13-Jets" in parameterName
or "2760-Jets" in parameterName
) :
process+=insert_ME("MEQCD2to2")
process+="set MEQCD2to2:MaximumFlavour 5\n"
process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
if "Jets-10" in parameterName : process+=jet_kt_cut(1800.)
elif "Jets-0" in parameterName : process+=jet_kt_cut(5.)
elif "Jets-1" in parameterName : process+=jet_kt_cut(10.)
elif "Jets-2" in parameterName : process+=jet_kt_cut(20.)
elif "Jets-3" in parameterName : process+=jet_kt_cut(40.)
elif "Jets-4" in parameterName : process+=jet_kt_cut(70.)
elif "Jets-5" in parameterName : process+=jet_kt_cut(150.)
elif "Jets-6" in parameterName : process+=jet_kt_cut(200.)
elif "Jets-7" in parameterName : process+=jet_kt_cut(300.)
elif "Jets-8" in parameterName : process+=jet_kt_cut(500.)
elif "Jets-9" in parameterName : process+=jet_kt_cut(800.)
elif( "-Charm" in parameterName or "-Bottom" in parameterName ) :
if("8-Bottom" in parameterName) :
addBRReweighter()
process+=selectDecayMode("Jpsi",["Jpsi->mu-,mu+;"])
if "Bottom" in parameterName :
process+="cp MEHeavyQuark MEBottom\n"
process+="set MEBottom:QuarkType Bottom\n"
process+=insert_ME("MEBottom")
else :
process+="cp MEHeavyQuark MECharm\n"
process+="set MECharm:QuarkType Charm\n"
process+=insert_ME("MECharm")
process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
if "-0" in parameterName :
if "Bottom" in parameterName :
process+="set MEBottom:Process Pair\n"
process+=jet_kt_cut(0.)
else :
process+=jet_kt_cut(1.)
elif "-1" in parameterName : process+=jet_kt_cut(5.)
elif "-2" in parameterName : process+=jet_kt_cut(15.)
elif "-3" in parameterName : process+=jet_kt_cut(20.)
elif "-4" in parameterName : process+=jet_kt_cut(50.)
elif "-5" in parameterName : process+=jet_kt_cut(80.)
elif "-6" in parameterName : process+=jet_kt_cut(110.)
elif "-7" in parameterName : process+=jet_kt_cut(30.)+mhat_cut(90.)
elif "-8" in parameterName : process+=jet_kt_cut(30.)+mhat_cut(340.)
elif "-9" in parameterName : process+=jet_kt_cut(30.)+mhat_cut(500.)
elif "Top-L" in parameterName :
process+="set MEHeavyQuark:QuarkType Top\n"
process+=insert_ME("MEHeavyQuark")
process+=selectDecayMode("t",["t->nu_e,e+,b;",
"t->nu_mu,mu+,b;"])
process+=addBRReweighter()
elif "Top-SL" in parameterName :
process+="set MEHeavyQuark:QuarkType Top\n"
process+=insert_ME("MEHeavyQuark")
process+="set /Herwig/Particles/t:Synchronized Not_synchronized\n"
process+="set /Herwig/Particles/tbar:Synchronized Not_synchronized\n"
process+=selectDecayMode("t",["t->nu_e,e+,b;","t->nu_mu,mu+,b;"])
process+=selectDecayMode("tbar",["tbar->b,bbar,cbar;",
"tbar->bbar,cbar,d;",
"tbar->bbar,cbar,s;",
"tbar->bbar,s,ubar;",
"tbar->bbar,ubar,d;"])
process+=addBRReweighter()
elif "Top-All" in parameterName :
process+="set MEHeavyQuark:QuarkType Top\n"
process+=insert_ME("MEHeavyQuark")
elif "WZ" in parameterName :
process+=insert_ME("MEPP2VV","WZ")
process+=selectDecayMode("W+",["W+->nu_e,e+;",
"W+->nu_mu,mu+;"])
process+=selectDecayMode("W-",["W-->nu_ebar,e-;",
"W-->nu_mubar,mu-;"])
process+=selectDecayMode("Z0",["Z0->e-,e+;",
"Z0->mu-,mu+;"])
addedBRReweighter = True
elif "WW-emu" in parameterName :
process+=insert_ME("MEPP2VV","WW")
process+="set /Herwig/Particles/W+:Synchronized 0\n"
process+="set /Herwig/Particles/W-:Synchronized 0\n"
process+=selectDecayMode("W+",["W+->nu_e,e+;"])
process+=selectDecayMode("W-",["W-->nu_mubar,mu-;"])
addedBRReweighter = True
elif "WW-ll" in parameterName :
process+=insert_ME("MEPP2VV","WW")
process+=selectDecayMode("W+",["W+->nu_e,e+;","W+->nu_mu,mu+;","W+->nu_tau,tau+;"])
addedBRReweighter = True
elif "ZZ-ll" in parameterName :
process+=insert_ME("MEPP2VV","ZZ")
process+=selectDecayMode("Z0",["Z0->e-,e+;",
"Z0->mu-,mu+;",
"Z0->tau-,tau+;"])
addedBRReweighter = True
elif "ZZ-lv" in parameterName :
process+=insert_ME("MEPP2VV","ZZ")
process+=selectDecayMode("Z0",["Z0->e-,e+;",
"Z0->mu-,mu+;",
"Z0->tau-,tau+;",
"Z0->nu_e,nu_ebar;",
"Z0->nu_mu,nu_mubar;",
"Z0->nu_tau,nu_taubar;"])
addedBRReweighter = True
elif "W-e" in parameterName :
process+=insert_ME("MEqq2W2ff","Electron")
elif "W-mu" in parameterName :
process+=insert_ME("MEqq2W2ff","Muon")
elif "Z-e" in parameterName or "Z-mu" in parameterName :
if "Z-e" in parameterName:
process+=insert_ME("MEqq2gZ2ff","Electron")
else :
process+=insert_ME("MEqq2gZ2ff","Muon")
mcuts=[10,35,75,110,400,ecms]
for i in range(1,6) :
tstring = "-Mass%s"%i
if tstring in parameterName :
process+=mhat_minm_maxm(mcuts[i-1],mcuts[i-1],mcuts[i])
parameterName=parameterName.replace(tstring,"")
elif "Z-nu" in parameterName :
process+=insert_ME("MEqq2gZ2ff","Neutrinos")
elif "W-Jet" in parameterName :
process+=insert_ME("MEWJet","Electron","WDecay")
if "W-Jet-1-e" in parameterName :
process+="set /Herwig/Cuts/WBosonKtCut:MinKT 100.0*GeV\n"
parameterName=parameterName.replace("W-Jet-1-e","W-Jet-e")
elif "W-Jet-2-e" in parameterName :
process+="set /Herwig/Cuts/WBosonKtCut:MinKT 190.0*GeV\n"
parameterName=parameterName.replace("W-Jet-2-e","W-Jet-e")
elif "W-Jet-3-e" in parameterName :
process+="set /Herwig/Cuts/WBosonKtCut:MinKT 270.0*GeV\n"
parameterName=parameterName.replace("W-Jet-3-e","W-Jet-e")
elif "Z-Jet" in parameterName :
if "-e" in parameterName :
process+=insert_ME("MEZJet","Electron","ZDecay")
if "Z-Jet-0-e" in parameterName :
process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 35.0*GeV\n"
parameterName=parameterName.replace("Z-Jet-0-e","Z-Jet-e")
elif "Z-Jet-1-e" in parameterName :
process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 100.0*GeV\n"
parameterName=parameterName.replace("Z-Jet-1-e","Z-Jet-e")
elif "Z-Jet-2-e" in parameterName :
process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 190.0*GeV\n"
parameterName=parameterName.replace("Z-Jet-2-e","Z-Jet-e")
elif "Z-Jet-3-e" in parameterName :
process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 270.0*GeV\n"
parameterName=parameterName.replace("Z-Jet-3-e","Z-Jet-e")
else :
process+=insert_ME("MEZJet","Muon","ZDecay")
process+="set /Herwig/Cuts/ZBosonKtCut:MinKT 35.0*GeV\n"
parameterName=parameterName.replace("Z-Jet-0-mu","Z-Jet-mu")
elif "WGamma" in parameterName :
process+=insert_ME("MEPP2VGamma","1")
process+="set MEPP2VGamma:MassOption 1"
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 10.\n"
if "-e" in parameterName :
process+=selectDecayMode("W+",["W+->nu_e,e+;"])
addedBRReweighter=True
else :
process+=selectDecayMode("W+",["W+->nu_mu,mu+;"])
addedBRReweighter=True
elif "ZGamma" in parameterName :
process+=insert_ME("MEPP2VGamma","2")
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 10.\n"
if "-e" in parameterName :
process+=selectDecayMode("Z0",["Z0->e-,e+;"])
addedBRReweighter=True
else :
process+=selectDecayMode("Z0",["Z0->mu-,mu+;"])
addedBRReweighter=True
else :
logging.error(" Process %s not supported for internal matrix elements" % name)
sys.exit(1)
elif(simulation=="Powheg") :
if "VBF" in parameterName :
process+=insert_ME("PowhegMEPP2HiggsVBF")
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
addedBRReweighter = True
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
addedBRReweighter = True
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
addedBRReweighter = True
elif "8-" not in parameterName :
process+=selectDecayMode("h0",["h0->tau-,tau+;"])
addedBRReweighter = True
process+="set /Herwig/Particles/tau-:Stable Stable\n"
elif "ggHJet" in parameterName :
logging.error(" Process %s not supported for POWHEG matrix elements" % name)
sys.exit(1)
elif "ggH" in parameterName :
process+=insert_ME("PowhegMEHiggs")
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
addedBRReweighter = True
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
addedBRReweighter = True
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
addedBRReweighter = True
elif "8-" not in parameterName :
process+=selectDecayMode("h0",["h0->tau-,tau+;"])
addedBRReweighter = True
process+="set /Herwig/Particles/tau-:Stable Stable\n"
elif "8-WH" in parameterName :
process+=insert_ME("PowhegMEPP2WH")
process+=jet_kt_cut(0.0)
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
addedBRReweighter = True
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
addedBRReweighter = True
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
addedBRReweighter = True
elif "8-ZH" in parameterName :
process+=insert_ME("PowhegMEPP2ZH")
process+=jet_kt_cut(0.0)
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
addedBRReweighter = True
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
addedBRReweighter = True
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
addedBRReweighter = True
elif "WH" in parameterName :
process+=selectDecayMode("h0",["h0->b,bbar;"])
process+=selectDecayMode("W+",["W+->nu_e,e+;",
"W+->nu_mu,mu+;"])
addedBRReweighter = True
process+=insert_ME("PowhegMEPP2WH")
process+=jet_kt_cut(0.0)
elif "ZH" in parameterName :
process+=selectDecayMode("h0",["h0->b,bbar;"])
process+=selectDecayMode("Z0",["Z0->e-,e+;",
"Z0->mu-,mu+;"])
addedBRReweighter = True
process+=insert_ME("PowhegMEPP2ZH")
process+=jet_kt_cut(0.0)
elif "UE" in parameterName :
logging.error(" Process %s not supported for powheg matrix elements" % name)
sys.exit(1)
elif "WZ" in parameterName :
process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n"
process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n"
process+="set /Herwig/Shower/ShowerHandler:SplitHardProcess No\n";
process+="set /Herwig/Decays/ZDecayer:PhotonGenerator NULL\n";
process+="set /Herwig/Decays/WDecayer:PhotonGenerator NULL\n";
process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n"
process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n"
process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n"
process+=insert_ME("PowhegMEPP2VV","WZ")
process+=selectDecayMode("W+",["W+->nu_e,e+;",
"W+->nu_mu,mu+;"])
process+=selectDecayMode("W-",["W-->nu_ebar,e-;",
"W-->nu_mubar,mu-;"])
process+=selectDecayMode("Z0",["Z0->e-,e+;",
"Z0->mu-,mu+;"])
addedBRReweighter = True
elif "WW-emu" in parameterName :
process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n"
process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n"
process+="set /Herwig/Shower/ShowerHandler:SplitHardProcess No\n";
process+="set /Herwig/Decays/ZDecayer:PhotonGenerator NULL\n";
process+="set /Herwig/Decays/WDecayer:PhotonGenerator NULL\n";
process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n"
process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n"
process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n"
process+=insert_ME("PowhegMEPP2VV","WW")
process+="set /Herwig/Particles/W+:Synchronized 0\n"
process+="set /Herwig/Particles/W-:Synchronized 0\n"
process+=selectDecayMode("W+",["W+->nu_e,e+;"])
process+=selectDecayMode("W-",["W-->nu_mubar,mu-;"])
addedBRReweighter = True
elif "WW-ll" in parameterName :
process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n"
process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n"
process+="set /Herwig/Shower/ShowerHandler:SplitHardProcess No\n";
process+="set /Herwig/Decays/ZDecayer:PhotonGenerator NULL\n";
process+="set /Herwig/Decays/WDecayer:PhotonGenerator NULL\n";
process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n"
process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n"
process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n"
process+=insert_ME("PowhegMEPP2VV","WW")
process+=selectDecayMode("W+",["W+->nu_e,e+;",
"W+->nu_mu,mu+;",
"W+->nu_tau,tau+;"])
addedBRReweighter = True
elif "ZZ-ll" in parameterName :
process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n"
process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n"
process+="set /Herwig/Shower/ShowerHandler:SplitHardProcess No\n";
process+="set /Herwig/Decays/ZDecayer:PhotonGenerator NULL\n";
process+="set /Herwig/Decays/WDecayer:PhotonGenerator NULL\n";
process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n"
process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n"
process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n"
process+=insert_ME("PowhegMEPP2VV","ZZ")
process+=selectDecayMode("Z0",["Z0->e-,e+;",
"Z0->mu-,mu+;",
"Z0->tau-,tau+;"])
addedBRReweighter = True
elif "ZZ-lv" in parameterName :
process+="create Herwig::HwDecayHandler /Herwig/NewPhysics/DecayHandler\n"
process+="set /Herwig/NewPhysics/DecayHandler:NewStep No\n"
process+="set /Herwig/Shower/ShowerHandler:SplitHardProcess No\n";
process+="set /Herwig/Decays/ZDecayer:PhotonGenerator NULL\n";
process+="set /Herwig/Decays/WDecayer:PhotonGenerator NULL\n";
process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 0 /Herwig/Particles/tau-\n"
process+="insert /Herwig/NewPhysics/DecayHandler:Excluded 1 /Herwig/Particles/tau+\n"
process+="insert /Herwig/Generators/EventGenerator:EventHandler:PreCascadeHandlers 0 /Herwig/NewPhysics/DecayHandler\n"
process+=insert_ME("PowhegMEPP2VV","ZZ")
process+=selectDecayMode("Z0",["Z0->e-,e+;",
"Z0->mu-,mu+;",
"Z0->tau-,tau+;",
"Z0->nu_e,nu_ebar;",
"Z0->nu_mu,nu_mubar;",
"Z0->nu_tau,nu_taubar;"])
addedBRReweighter = True
elif "W-e" in parameterName :
process+=insert_ME("PowhegMEqq2W2ff","Electron")
elif "W-mu" in parameterName :
process+=insert_ME("PowhegMEqq2W2ff","Muon")
elif "Z-e" in parameterName or "Z-mu" in parameterName :
if "Z-e" in parameterName:
process+=insert_ME("PowhegMEqq2gZ2ff","Electron")
else :
process+=insert_ME("PowhegMEqq2gZ2ff","Muon")
mcuts=[10,35,75,110,400,ecms]
for i in range(1,6) :
tstring = "-Mass%s"%i
if tstring in parameterName :
process+=mhat_minm_maxm(mcuts[i-1],mcuts[i-1],mcuts[i])
parameterName=parameterName.replace(tstring,"")
elif "Z-nu" in parameterName :
process+=insert_ME("PowhegMEqq2gZ2ff","Neutrinos")
elif "DiPhoton-GammaGamma" in parameterName :
process+=insert_ME("MEGammaGammaPowheg","GammaGamma")
process+=insert_ME("MEGammaGamma","gg")
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
process+=jet_kt_cut(5.)
parameterName=parameterName.replace("-GammaGamma","")
elif "DiPhoton-GammaJet" in parameterName :
process+=insert_ME("MEGammaGammaPowheg","VJet")
process+="set /Herwig/Cuts/PhotonKtCut:MinKT 5.\n"
process+=jet_kt_cut(5.)
parameterName=parameterName.replace("-GammaJet","")
else :
logging.error(" Process %s not supported for internal POWHEG matrix elements" % name)
sys.exit(1)
elif( simulation=="Matchbox" or simulation=="Merging" ) :
if "VBF" in parameterName :
parameters["nlo"] = "read Matchbox/VBFNLO.in\n"
if(simulation=="Merging"):
process+="cd /Herwig/Merging/\n"
process+="insert "+thefactory+":DiagramGenerator:RestrictLines 0 /Herwig/Particles/Z0\n"
process+="insert "+thefactory+":DiagramGenerator:RestrictLines 0 /Herwig/Particles/W+\n"
process+="insert "+thefactory+":DiagramGenerator:RestrictLines 0 /Herwig/Particles/W-\n"
process+="insert "+thefactory+":DiagramGenerator:RestrictLines 0 /Herwig/Particles/gamma\n"
process+="do "+thefactory+":DiagramGenerator:TimeLikeRange 0 0\n"
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p h0 j j","0","3","FixedScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p h0 j j","0","3","FixedScale",1,1)
process+=setHardProcessWidthToZero(["h0"])
process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
process+=addBRReweighter()
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
process+=addBRReweighter()
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
process+=addBRReweighter()
elif "8-" not in parameterName :
process+=selectDecayMode("h0",["h0->tau-,tau+;"])
process+=addBRReweighter()
process+="set /Herwig/Particles/tau-:Stable Stable\n"
elif "ggHJet" in parameterName :
if(simulation=="Merging"):
logging.warning("ggHJet not explicitly tested for %s " % simulation)
sys.exit(0)
parameters["nlo"] = "read Matchbox/MadGraph-GoSam.in\nread Matchbox/HiggsEffective.in\n"
process+=selectDecayMode("h0",["h0->tau-,tau+;"])
process+=addBRReweighter()
process+="set /Herwig/Particles/tau-:Stable Stable\n"
process+=setHardProcessWidthToZero(["h0"])
process+=addProcess(thefactory,"p p h0 j","3","1","FixedScale",0,0)
process+=addFirstJet("20")
process+="set "+thefactory+":ScaleChoice /Herwig/MatrixElements/Matchbox/Scales/FixedScale\n"
process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
elif "ggH" in parameterName :
parameters["nlo"] = "read Matchbox/MadGraph-GoSam.in\nread Matchbox/HiggsEffective.in\n"
if(simulation=="Merging"):
process+= "cd /Herwig/MatrixElements/Matchbox/Amplitudes\nset OpenLoops:HiggsEff Yes\nset MadGraph:Model heft\n"
process+="cd /Herwig/Merging/\n"
process+=setHardProcessWidthToZero(["h0"])
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p h0","2","1","FixedScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p h0","2","1","FixedScale",2,2)
process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
process+=addBRReweighter()
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
process+=addBRReweighter()
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
process+=addBRReweighter()
elif "8-" not in parameterName :
process+=selectDecayMode("h0",["h0->tau-,tau+;"])
process+=addBRReweighter()
process+="set /Herwig/Particles/tau-:Stable Stable\n"
elif "8-WH" in parameterName :
if(simulation=="Merging"):
logging.warning("8-WH not explicitly tested for %s " % simulation)
sys.exit(0)
process+=setHardProcessWidthToZero(["h0","W+","W-"])
process+=addProcess(thefactory,"p p W+ h0","0","2","FixedScale",0,0)
process+=addProcess(thefactory,"p p W- h0","0","2","FixedScale",0,0)
process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
process+=addBRReweighter()
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
process+=addBRReweighter()
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
process+=addBRReweighter()
elif "8-ZH" in parameterName :
if(simulation=="Merging"):
logging.warning("8-ZH not explicitly tested for %s " % simulation)
sys.exit(0)
process+=setHardProcessWidthToZero(["h0","Z0"])
process+=addProcess(thefactory,"p p Z0 h0","0","2","FixedScale",0,0)
process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 125.7\n"
if "GammaGamma" in parameterName :
process+=selectDecayMode("h0",["h0->gamma,gamma;"])
process+=addBRReweighter()
elif "WW" in parameterName :
process+=selectDecayMode("h0",["h0->W+,W-;"])
process+=addBRReweighter()
elif "ZZ" in parameterName :
process+=selectDecayMode("h0",["h0->Z0,Z0;"])
process+=addBRReweighter()
elif "WH" in parameterName :
if(simulation=="Merging"):
logging.warning("WH not explicitly tested for %s " % simulation)
sys.exit(0)
process+=selectDecayMode("h0",["h0->b,bbar;"])
process+=addBRReweighter()
process+=setHardProcessWidthToZero(["h0"])
process+=addProcess(thefactory,"p p e+ nu h0","0","3","LeptonPairMassScale",0,0)
process+=addProcess(thefactory,"p p e- nu h0","0","3","LeptonPairMassScale",0,0)
process+=addProcess(thefactory,"p p mu+ nu h0","0","3","LeptonPairMassScale",0,0)
process+=addProcess(thefactory,"p p mu- nu h0","0","3","LeptonPairMassScale",0,0)
process+=addLeptonPairCut("60","120")
elif "ZH" in parameterName :
if(simulation=="Merging"):
logging.warning("ZH not explicitly tested for %s " % simulation)
sys.exit(0)
process+=selectDecayMode("h0",["h0->b,bbar;"])
process+=addBRReweighter()
process+=setHardProcessWidthToZero(["h0"])
process+=addProcess(thefactory,"p p e+ e- h0","0","3","LeptonPairMassScale",0,0)
process+=addProcess(thefactory,"p p mu+ mu- h0","0","3","LeptonPairMassScale",0,0)
process+=addLeptonPairCut("60","120")
elif "UE" in parameterName :
logging.error(" Process %s not supported for Matchbox matrix elements" % name)
sys.exit(1)
elif "8-DiJets" in parameterName or "7-DiJets" in parameterName or "13-DiJets" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p j j","2","0","MaxJetPtScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p j j","2","0","MaxJetPtScale",1,1)
process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
if "13-DiJets" not in parameterName :
if "-A" in parameterName :
process+=addFirstJet("45")
process+=addSecondJet("25")
process+="set /Herwig/Cuts/FirstJet:YRange -3. 3.\n"
process+="set /Herwig/Cuts/SecondJet:YRange -3. 3.\n"
elif "-B" in parameterName :
process+=addFirstJet("20")
process+=addSecondJet("15")
process+="set /Herwig/Cuts/FirstJet:YRange -2.7 2.7\n"
process+="set /Herwig/Cuts/SecondJet:YRange -2.7 2.7\n"
elif "-C" in parameterName :
process+=addFirstJet("20")
process+=addSecondJet("15")
process+="set /Herwig/Cuts/FirstJet:YRange -4.8 4.8\n"
process+="set /Herwig/Cuts/SecondJet:YRange -4.8 4.8\n"
else :
logging.error("Exit 00001")
sys.exit(1)
else :
if "-A" in parameterName :
process+= addFirstJet("75.")
process+=addSecondJet("60.")
process+="set /Herwig/Cuts/JetKtCut:MinEta -3.\n"
process+="set /Herwig/Cuts/JetKtCut:MaxEta 3.\n"
elif "-B" in parameterName :
process+= addFirstJet("220.")
process+=addSecondJet("180.")
process+="set /Herwig/Cuts/JetKtCut:MinEta -3.\n"
process+="set /Herwig/Cuts/JetKtCut:MaxEta 3.\n"
else :
logging.error("Exit 00001")
sys.exit(1)
if "DiJets-1" in parameterName : process+=addJetPairCut("90")
elif "DiJets-2" in parameterName : process+=addJetPairCut("200")
elif "DiJets-3" in parameterName : process+=addJetPairCut("450")
elif "DiJets-4" in parameterName : process+=addJetPairCut("750")
elif "DiJets-5" in parameterName : process+=addJetPairCut("950")
elif "DiJets-6" in parameterName : process+=addJetPairCut("1550")
elif "DiJets-7" in parameterName : process+=addJetPairCut("2150")
elif "DiJets-8" in parameterName : process+=addJetPairCut("2750")
elif "DiJets-9" in parameterName : process+=mhat_cut(3750.)
elif "DiJets-10" in parameterName : process+=mhat_cut(4750.)
elif "DiJets-11" in parameterName : process+=mhat_cut(5750.)
else :
logging.error("Exit 00002")
sys.exit(1)
elif( "7-Jets" in parameterName
or "8-Jets" in parameterName
or "13-Jets" in parameterName
or "2760-Jets" in parameterName
) :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p j j","2","0","MaxJetPtScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p j j","2","0","MaxJetPtScale",1,1)
process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
if "Jets-10" in parameterName : process+=addFirstJet("1800")
elif "Jets-0" in parameterName : process+=addFirstJet("5")
elif "Jets-1" in parameterName : process+=addFirstJet("10")
elif "Jets-2" in parameterName : process+=addFirstJet("20")
elif "Jets-3" in parameterName : process+=addFirstJet("40")
elif "Jets-4" in parameterName : process+=addFirstJet("70")
elif "Jets-5" in parameterName : process+=addFirstJet("150")
elif "Jets-6" in parameterName : process+=addFirstJet("200")
elif "Jets-7" in parameterName : process+=addFirstJet("300")
elif "Jets-8" in parameterName : process+=addFirstJet("500")
elif "Jets-9" in parameterName : process+=addFirstJet("800")
else :
logging.error("Exit 00003")
sys.exit(1)
elif( "-Charm" in parameterName or "-Bottom" in parameterName) :
parameters["bscheme"]=fourFlavour
process+="set /Herwig/Particles/b:HardProcessMass 4.2*GeV\n"
process+="set /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n"
if("8-Bottom" in parameterName) :
addBRReweighter()
process+=selectDecayMode("Jpsi",["Jpsi->mu-,mu+;"])
if "Bottom" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p b bbar","2","0","MaxJetPtScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p b bbar","2","0","MaxJetPtScale",1,0)
else:
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p c cbar","2","0","MaxJetPtScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p c cbar","2","0","MaxJetPtScale",1,0)
process+="set /Herwig/UnderlyingEvent/MPIHandler:IdenticalToUE 0\n"
if "-0" in parameterName : process+=addFirstJet("0")
elif "-1" in parameterName : process+=addFirstJet("5")
elif "-2" in parameterName : process+=addFirstJet("15")
elif "-3" in parameterName : process+=addFirstJet("20")
elif "-4" in parameterName : process+=addFirstJet("50")
elif "-5" in parameterName : process+=addFirstJet("80")
elif "-6" in parameterName : process+=addFirstJet("110")
elif "-7" in parameterName :
process+=addFirstJet("30")
process+=addSecondJet("25")
process+=addJetPairCut("90")
elif "-8" in parameterName :
process+=addFirstJet("30")
process+=addSecondJet("25")
process+=addJetPairCut("340")
elif "-9" in parameterName :
process+=addFirstJet("30")
process+=addSecondJet("25")
process+=addJetPairCut("500")
else :
logging.error("Exit 00004")
sys.exit(1)
elif "Top-L" in parameterName :
process+=setHardProcessWidthToZero(["t","tbar"])
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",2,2)
process+=selectDecayMode("t",["t->nu_e,e+,b;",
"t->nu_mu,mu+,b;"])
process+=addBRReweighter()
elif "Top-SL" in parameterName :
process+=setHardProcessWidthToZero(["t","tbar"])
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",2,2)
process+="set /Herwig/Particles/t:Synchronized Not_synchronized\n"
process+="set /Herwig/Particles/tbar:Synchronized Not_synchronized\n"
process+=selectDecayMode("t",["t->nu_e,e+,b;",
"t->nu_mu,mu+,b;"])
process+=selectDecayMode("tbar",["tbar->b,bbar,cbar;",
"tbar->bbar,cbar,d;",
"tbar->bbar,cbar,s;",
"tbar->bbar,s,ubar;",
"tbar->bbar,ubar,d;"])
process+=addBRReweighter()
elif "Top-All" in parameterName :
process+=setHardProcessWidthToZero(["t","tbar"])
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p t tbar","2","0","TopPairMTScale",2,2)
elif "WZ" in parameterName :
if(simulation=="Merging"):
logging.warning("WZ not explicitly tested for %s " % simulation)
sys.exit(0)
process+=setHardProcessWidthToZero(["W+","W-","Z0"])
process+=addProcess(thefactory,"p p W+ Z0","0","2","FixedScale",0,0)
process+=addProcess(thefactory,"p p W- Z0","0","2","FixedScale",0,0)
process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 171.6*GeV\n\n"
process+=selectDecayMode("W+",["W+->nu_e,e+;",
"W+->nu_mu,mu+;"])
process+=selectDecayMode("W-",["W-->nu_ebar,e-;",
"W-->nu_mubar,mu-;"])
process+=selectDecayMode("Z0",["Z0->e-,e+;",
"Z0->mu-,mu+;"])
process+=addBRReweighter()
process+=addLeptonPairCut("60","120")
elif "WW-emu" in parameterName :
if(simulation=="Merging"):
logging.warning("WW-emu not explicitly tested for %s " % simulation)
sys.exit(0)
process+=setHardProcessWidthToZero(["W+","W-","Z0"])
process+=addProcess(thefactory,"p p W+ W-","0","2","FixedScale",0,0)
process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 160.8*GeV\n"
process+="set /Herwig/Particles/W+:Synchronized 0\n"
process+="set /Herwig/Particles/W-:Synchronized 0\n"
process+=selectDecayMode("W+",["W+->nu_e,e+;"])
process+=selectDecayMode("W-",["W-->nu_mubar,mu-;"])
process+=addBRReweighter()
parameters["bscheme"] = "read Matchbox/FourFlavourScheme.in\n"
process+=addLeptonPairCut("60","120")
elif "WW-ll" in parameterName :
if(simulation=="Merging"):
logging.warning("WW-ll not explicitly tested for %s " % simulation)
sys.exit(0)
process+=setHardProcessWidthToZero(["W+","W-","Z0"])
process+=addProcess(thefactory,"p p W+ W-","0","2","FixedScale",0,0)
process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 160.8*GeV\n"
process+=selectDecayMode("W+",["W+->nu_e,e+;",
"W+->nu_mu,mu+;",
"W+->nu_tau,tau+;"])
process+=addBRReweighter()
process+=addLeptonPairCut("60","120")
parameters["bscheme"] = "read Matchbox/FourFlavourScheme.in\n"
elif "ZZ-ll" in parameterName :
if(simulation=="Merging"):
logging.warning("ZZ-ll not explicitly tested for %s " % simulation)
sys.exit(0)
process+=setHardProcessWidthToZero(["W+","W-","Z0"])
process+=addProcess(thefactory,"p p Z0 Z0","0","2","FixedScale",0,0)
process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 182.2*GeV\n"
process+=selectDecayMode("Z0",["Z0->e-,e+;",
"Z0->mu-,mu+;",
"Z0->tau-,tau+;"])
process+=addBRReweighter()
process+=addLeptonPairCut("60","120")
elif "ZZ-lv" in parameterName :
if(simulation=="Merging"):
logging.warning("ZZ-lv not explicitly tested for %s " % simulation)
sys.exit(0)
process+=setHardProcessWidthToZero(["W+","W-","Z0"])
process+=addProcess(thefactory,"p p Z0 Z0","0","2","FixedScale",0,0)
process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 182.2*GeV\n"
process+=selectDecayMode("Z0",["Z0->e-,e+;",
"Z0->mu-,mu+;",
"Z0->tau-,tau+;",
"Z0->nu_e,nu_ebar;",
"Z0->nu_mu,nu_mubar;",
"Z0->nu_tau,nu_taubar;"])
process+=addBRReweighter()
process+=addLeptonPairCut("60","120")
elif "W-e" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p e+ nu","0","2","LeptonPairMassScale",0,0)
process+=addProcess(thefactory,"p p e- nu","0","2","LeptonPairMassScale",0,0)
elif(simulation=="Merging"):
process+=particlegroup(thefactory,'epm','e+','e-')
process+=addProcess(thefactory,"p p epm nu","0","2","LeptonPairMassScale",2,2)
process+=addLeptonPairCut("60","120")
elif "W-mu" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p mu+ nu","0","2","LeptonPairMassScale",0,0)
process+=addProcess(thefactory,"p p mu- nu","0","2","LeptonPairMassScale",0,0)
elif(simulation=="Merging"):
process+=particlegroup(thefactory,'mupm','mu+','mu-')
process+=addProcess(thefactory,"p p mupm nu","0","2","LeptonPairMassScale",2,2)
process+=addLeptonPairCut("60","120")
elif "Z-e" in parameterName or "Z-mu" in parameterName :
if "Z-e" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p e+ e-","0","2","LeptonPairMassScale",2,2)
elif "Z-mu" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p mu+ mu-","0","2","LeptonPairMassScale",2,2)
mcuts=[10,35,75,110,400,ecms]
for i in range(1,6) :
tstring = "-Mass%s"%i
if tstring in parameterName :
process+=addLeptonPairCut(mcuts[i-1],mcuts[i])
parameterName=parameterName.replace(tstring,"")
elif "Z-nu" in parameterName :
if(simulation=="Matchbox"):
process+=addProcess(thefactory,"p p nu nu","0","2","LeptonPairMassScale",0,0)
elif(simulation=="Merging"):
process+=addProcess(thefactory,"p p nu nu","0","2","LeptonPairMassScale",2,2)
elif "Z-jj" in parameterName :
if(simulation=="Merging"):
logging.warning("Z-jj not explicitly tested for %s " % simulation)
sys.exit(0)
process+=addProcess(thefactory,"p p e+ e- j j","2","2","LeptonPairMassScale",0,0)
process+=addFirstJet("40")
process+=addSecondJet("30")
process+=addLeptonPairCut("60","120")
elif "W-Jet" in parameterName :
if(simulation=="Merging"):
logging.warning("W-Jet not explicitly tested for %s " % simulation)
sys.exit(0)
process+=addProcess(thefactory,"p p e+ nu j","1","2","HTScale",0,0)
process+=addProcess(thefactory,"p p e- nu j","1","2","HTScale",0,0)
process+=addLeptonPairCut("60","120")
if "W-Jet-1-e" in parameterName :
process+=addFirstJet("100")
parameterName=parameterName.replace("W-Jet-1-e","W-Jet-e")
elif "W-Jet-2-e" in parameterName :
process+=addFirstJet("190")
parameterName=parameterName.replace("W-Jet-2-e","W-Jet-e")
elif "W-Jet-3-e" in parameterName :
process+=addFirstJet("270")
parameterName=parameterName.replace("W-Jet-3-e","W-Jet-e")
else :
logging.error("Exit 00005")
sys.exit(1)
elif "Z-Jet" in parameterName :
if(simulation=="Merging"):
logging.warning("Z-Jet not explicitly tested for %s " % simulation)
sys.exit(0)
if "-e" in parameterName :
process+=addProcess(thefactory,"p p e+ e- j","1","2","HTScale",0,0)
if "Z-Jet-0-e" in parameterName :
process+=addFirstJet("35")
parameterName=parameterName.replace("Z-Jet-0-e","Z-Jet-e")
elif "Z-Jet-1-e" in parameterName :
process+=addFirstJet("100")
parameterName=parameterName.replace("Z-Jet-1-e","Z-Jet-e")
elif "Z-Jet-2-e" in parameterName :
process+=addFirstJet("190")
parameterName=parameterName.replace("Z-Jet-2-e","Z-Jet-e")
elif "Z-Jet-3-e" in parameterName :
process+=addFirstJet("270")
parameterName=parameterName.replace("Z-Jet-3-e","Z-Jet-e")
else :
logging.error("Exit 00006")
sys.exit(1)
else :
process+=addProcess(thefactory,"p p mu+ mu- j","1","2","HTScale",0,0)
process+=addFirstJet("35")
parameterName=parameterName.replace("Z-Jet-0-mu","Z-Jet-mu")
process+=addLeptonPairCut("60","120")
elif "Z-bb" in parameterName :
if(simulation=="Merging"):
logging.warning("Z-bb not explicitly tested for %s " % simulation)
sys.exit(0)
parameters["bscheme"]=fourFlavour
process+="set /Herwig/Particles/b:HardProcessMass 4.2*GeV\nset /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n"
process+=addProcess(thefactory,"p p e+ e- b bbar","2","2","FixedScale",0,0)
process+=addLeptonPairCut("66","116")
process+=addFirstJet("18")
process+=addSecondJet("15")
process+=addLeptonPairCut("60","120")
elif "Z-b" in parameterName :
if(simulation=="Merging"):
logging.warning("Z-b not explicitly tested for %s " % simulation)
sys.exit(0)
process+=particlegroup(thefactory,'bjet','b','bbar')
process+=addProcess(thefactory,"p p e+ e- bjet","1","2","FixedScale",0,0)
process+="set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 91.2*GeV\n"
process+=addLeptonPairCut("60","120")
process+=addFirstJet("15")
elif "W-b" in parameterName :
if(simulation=="Merging"):
logging.warning("W-b not explicitly tested for %s " % simulation)
sys.exit(0)
parameters["bscheme"]=fourFlavour
process += "set /Herwig/Particles/b:HardProcessMass 4.2*GeV\nset /Herwig/Particles/bbar:HardProcessMass 4.2*GeV\n"
process+=addProcess(thefactory,"p p e- nu b bbar","2","2","FixedScale",0,0)
process+=addProcess(thefactory,"p p mu+ nu b bbar","2","2","FixedScale",0,0)
process += "set /Herwig/MatrixElements/Matchbox/Scales/FixedScale:FixedScale 80.4*GeV\n"
process+=addFirstJet("30")
process+=addLeptonPairCut("60","120")
else :
logging.error(" Process %s not supported for Matchbox matrix elements" % name)
sys.exit(1)
# LHC-GammaGamma
elif(collider=="LHC-GammaGamma" ) :
if "-7-" in parameterName : process = StringBuilder(collider_lumi(7000.0))
elif "-8-" in parameterName : process = StringBuilder(collider_lumi(8000.0))
else : process = StringBuilder(collider_lumi(7000.0))
if(simulation=="") :
if "7" in parameterName : process += insert_ME("MEgg2ff","Muon")
else :
logging.error(" Process %s not supported for default matrix elements" % name)
sys.exit(1)
else :
logging.error("LHC-GammaGamma not supported for %s " % simulation)
sys.exit(1)
if "EHS" in name :
pFile = os.path.join(collider,"{c}-{pn}.in".format(c="EHS", pn=parameterName))
else :
pFile = os.path.join(collider,"{c}-{pn}.in".format(c=collider, pn=parameterName))
with open(os.path.join("Rivet",pFile), 'r') as f:
parameters['parameterFile'] = f.read()
parameters['runname'] = 'Rivet-%s' % name
parameters['process'] = str(process)
if have_hadronic_collider :
if "EHS" in name :
parameters['collider'] = "PPCollider.in\nread snippets/FixedTarget-PP.in"
else :
parameters['collider'] = "PPCollider.in"
#check if selecteddecaymode and addedBRReweighter is consistent
if selecteddecaymode and not addedBRReweighter:
logging.error("Decaymode was selected but no BRReweighter was added.")
sys.exit(1)
if addedBRReweighter and not selecteddecaymode:
logging.error("BRReweighter was added but no Decaymode was selected.")
sys.exit(1)
# check that we only add one process if in merging mode:
if numberOfAddedProcesses > 1 and simulation =="Merging":
logging.error("In Merging only one process is allowed at the moment. See ticket #403.")
sys.exit(1)
# Check if a process was added for Merging or Matchbox:
if numberOfAddedProcesses == 0 and (simulation =="Merging" or simulation =="Matchbox"):
logging.error("No process was selected.")
sys.exit(1)
# get template and write the file
-
with open(os.path.join("Rivet/Templates",templateName), 'r') as f:
templateText = f.read()
template = Template( templateText )
with open(os.path.join("Rivet",name+".in"), 'w') as f:
f.write( template.substitute(parameters) )
diff --git a/Tests/python/merge-DIS.in b/Tests/python/merge-DIS.in
--- a/Tests/python/merge-DIS.in
+++ b/Tests/python/merge-DIS.in
@@ -1,100 +1,95 @@
#! @PYTHON@
from __future__ import print_function
import logging, sys,subprocess,math,time
if sys.version_info[:3] < (2,4,0):
print ("rivet scripts require Python version >= 2.4.0... exiting")
sys.exit(1)
import os, yoda
# #############################################
if __name__ == "__main__":
import logging
from optparse import OptionParser, OptionGroup
parser = OptionParser(usage="%prog name")
verbgroup = OptionGroup(parser, "Verbosity control")
verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL",
default=logging.INFO, help="print debug (very verbose) messages")
verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL",
default=logging.INFO, help="be very quiet")
parser.add_option_group(verbgroup)
(opts, args) = parser.parse_args()
logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s")
## Check args
if len(args) < 1:
logging.error("Must specify at least the name of the files")
sys.exit(1)
# #######################################
yodafiles=[]
for energy in [225,251,296,300,318,"318-CMS"] :
for process in ["e+","e-","e+-CC","e--CC","e+"] :
mergeargs=["rivet-merge"]
for q2 in ["VeryLow","Low","Med","High"] :
fname = "Rivet-%s-%s-%s-%sQ2.yoda" % (args[0], energy ,process,q2)
if(os.path.isfile(fname)) :
mergeargs.append(fname)
if len(mergeargs)==1 : continue
if "e+" in process : beam="EPLUS"
else : beam="EMINUS"
if type(energy) == int :
mergeargs.append("-a")
mergeargs.append("HERA_2015_I1377206:ENERGY=%s"%energy)
mergeargs.append("-a")
mergeargs.append("HERA_2015_I1377206:BEAM=%s" %beam)
fname = "Rivet-%s-%s-%s.yoda"% (args[0], energy ,process)
mergeargs.append("-o")
mergeargs.append(fname)
yodafiles.append(fname)
p = subprocess.Popen(mergeargs)
# need a sleep here otherwise merged files not ready
-time.sleep(2)
+time.sleep(5)
## Get histos
-inhistos = {}
outhistos={}
-weights = {}
for f in yodafiles:
if not os.access(f, os.R_OK):
logging.error("%s can not be read" % f)
continue
try:
aos = yoda.read(f)
except:
logging.error("%s can not be parsed as YODA" % f)
continue
## Get histos from this YODA file
for aopath, ao in aos.items() :
if("RAW" in aopath) : continue
elif(aopath.find("_XSEC")>=0 or aopath.find("_EVTCOUNT")>=0) :
continue
elif "HERA_2015_I1377206" in aopath :
path=aopath.split(":")
ao.setPath(path[0]+"/"+path[2].split("/")[1])
if "d06" in aopath or "d07" in aopath :
if "CC" in f : outhistos[aopath] = ao
else :
if "CC" not in f : outhistos[aopath] = ao
else :
outhistos[aopath] = ao
-
-# H1_1995_I394793
-
# Choose output file
name = args[0]+".yoda"
# remove any scatters with nans, causes yoda to crash
remove = []
for key in outhistos.keys() :
ao = outhistos[key]
if type(ao)==yoda.core.Scatter2D :
skip=False
for p in ao.points() :
if math.isnan(p.y()) : skip=True
if(skip) : remove.append(key)
for key in remove : del outhistos[key]
# output the yoda file
yoda.writeYODA(outhistos,name)
sys.exit(0)
diff --git a/Tests/python/merge-EE-Gamma.in b/Tests/python/merge-EE-Gamma.in
--- a/Tests/python/merge-EE-Gamma.in
+++ b/Tests/python/merge-EE-Gamma.in
@@ -1,137 +1,138 @@
#! @PYTHON@
+# -*- mode: python -*-
from __future__ import print_function
import logging,sys, os, yoda, copy
if sys.version_info[:3] < (2,4,0):
print ("rivet scripts require Python version >= 2.4.0... exiting")
sys.exit(1)
#############################################
def fillAbove(desthisto, sourcehistosbysqrts):
if type(desthisto) is yoda.core.Scatter2D :
for sqrts in sorted(sourcehistosbysqrts.keys()) :
h=sourcehistosbysqrts[sqrts]
for i in range(0,h.numPoints()) :
if sqrts==h.points()[i].x() :
desthisto.addPoint(h.points()[i])
elif(type(desthisto)==yoda.core.Profile1D) :
for sqrts, h in sorted(sourcehistosbysqrts.items()) :
for i in range(0,h.numBins()) :
if(sqrts>=h.bins()[i].xMin() and \
sqrts<=h.bins()[i].xMax()) :
desthisto.bins()[i] += h.bins()[i]
break
else :
logging.error("Unknown analysis object" + desthisto.path)
sys.exit(1)
def merge(hpath):
global inhistos
global outhistos
try:
fillAbove(outhistos[hpath], inhistos[hpath])
except:
pass
def useOne(hpath, sqrts):
global inhistos
global outhistos
try:
outhistos[hpath] = inhistos[hpath][float(sqrts)]
except:
pass
if __name__ == "__main__":
import logging
from optparse import OptionParser, OptionGroup
parser = OptionParser(usage="%prog name")
verbgroup = OptionGroup(parser, "Verbosity control")
verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL",
default=logging.INFO, help="print debug (very verbose) messages")
verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL",
default=logging.INFO, help="be very quiet")
parser.add_option_group(verbgroup)
(opts, args) = parser.parse_args()
logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s")
## Check args
if len(args) < 1:
logging.error("Must specify at least the name of the files")
sys.exit(1)
#######################################
yodafiles=["-Direct-mumu-161","-Direct-mumu-172","-Direct-mumu-183",
"-Direct-mumu-189","-Direct-mumu-196","-Direct-mumu-206",
"-Direct-tautau-189","-Direct-tautau-196","-Direct-tautau-206",
"-Direct-Jets-198","-Single-Resolved-Jets-198","-Double-Resolved-Jets-198",
"-Direct-Jets-206","-Single-Resolved-Jets-206","-Double-Resolved-Jets-206",]
# Get histos
inhistos = {}
outhistos = {}
for f in yodafiles:
file = "Rivet-%s%s.yoda" % (args[0], f)
sqrts=float(f.split("-")[-1].replace(".yoda",""))
if not os.access(file, os.R_OK):
logging.error("%s cannot be read" % file)
continue
try:
aos = yoda.read(file)
except:
logging.error("%s cannot be parsed as yoda" % file)
continue
## Get histos from this YODA file
for aopath, ao in aos.items() :
if("RAW" in aopath or "_XSEC" in aopath or "_EVTCOUNT" in aopath ) :continue
# merge of different energy values
if("L3_2004_I645127" in aopath) :
if(("d01" in aopath and "mu" in file) or
("d02" in aopath and "tau" in file)) :
if aopath not in inhistos :
inhistos[aopath] = {}
if sqrts not in inhistos[aopath]:
inhistos[aopath][sqrts] = ao
else:
raise Exception("A set with sqrts = %s already exists" % ( sqrts))
else :
if(aopath in outhistos) :
outhistos[aopath] += ao
else :
outhistos[aopath] = ao
## Make empty output histos if needed
for hpath,hsets in inhistos.items():
if("L3_2004_I645127" in hpath ) :
histo = list(hsets.values())[0]
if(type(histo)==yoda.core.Scatter2D) :
outhistos[hpath] = yoda.core.Scatter2D(histo.path(),
histo.title())
elif(type(histo)==yoda.core.Profile1D) :
outhistos[hpath] = yoda.core.Profile1D(histo.path(),
histo.title())
for i in range(0,histo.numBins) :
outhistos[hpath].addBin(histo.bins()[i].xMin(),
histo.bins()[i].xMax())
elif(type(histo)==yoda.core.Histo1D) :
outhistos[hpath] = yoda.core.Histo1D(histo.path(),
histo.title())
for i in range(0,histo.numBins) :
outhistos[hpath].addBin(histo.bins()[i].xMin(),
histo.bins()[i].xMax())
else :
logging.error("Histogram %s is of unknown type" % hpath)
sys.exit(1)
merge("/L3_2004_I645127/d01-x01-y01")
merge("/L3_2004_I645127/d01-x01-y02")
merge("/L3_2004_I645127/d02-x01-y01")
# Choose output file
name = args[0]+".yoda"
# output the yoda file
print ("Write yoda to ",name)
yoda.writeYODA(outhistos,name)
sys.exit(0)
diff --git a/Tests/python/merge-EE.in b/Tests/python/merge-EE.in
--- a/Tests/python/merge-EE.in
+++ b/Tests/python/merge-EE.in
@@ -1,1344 +1,1439 @@
#! @PYTHON@
+# -*- mode: python -*-
from __future__ import print_function
import logging
import sys
+import math
if sys.version_info[:3] < (2,4,0):
print ("rivet scripts require Python version >= 2.4.0... exiting")
sys.exit(1)
import os, yoda, copy
# # #############################################
+# remove any scatters with nans, causes yoda to crash
+def removeNan():
+ global outhistos
+ remove = []
+ for key in outhistos.keys() :
+ ao = outhistos[key]
+ if type(ao)==yoda.core.Scatter2D :
+ skip=False
+ for p in ao.points() :
+ if ( math.isnan(p.y()) or
+ math.isnan(p.yErrs().minus) or math.isnan(p.yErrs().plus)) :
+ skip=True
+ break
+ if(skip) : remove.append(key)
+ for key in remove :
+ if key in outhistos : del outhistos[key]
+
def fillAbove(desthisto, sourcehistosbysqrts):
if type(desthisto) is yoda.core.Scatter2D :
temp={}
for (key,val) in sourcehistosbysqrts.items():
if key=="U1" :
sqrts=9.46
if "LENA_1981_I164397" in desthisto.path() : sqrts=9.4624
elif key=="U2" :
sqrts=10.02
if "LENA_1981_I164397" in desthisto.path() : sqrts=10.0148
elif key=="U4" :
sqrts=10.58
else :
sqrts=float(key)
if ("ARGUS_1989_I276860" in desthisto.path() and sqrts==10. ) : sqrts=9.98
elif ( "LENA_1981_I164397" in desthisto.path() and sqrts==10. ) : sqrts=9.9903
elif ( "LENA_1981_I164397" in desthisto.path() and sqrts==9.51) : sqrts=9.5149
temp[sqrts]=val
for sqrts,h in sorted(temp.items()) :
step = 0.001
if("TASSO_1980_I143691" in desthisto.path()) : step=0.3
if("JADE_1979_I142874" in desthisto.path()) : step=0.3
if("CLEO_1985_I205668" in desthisto.path()) : step=0.05
for i in range(0,h.numPoints()) :
xmin = min(h.points()[i].xMin(),h.points()[i].x()-step)
xmax = max(h.points()[i].xMax(),h.points()[i].x()+step)
if(sqrts>=xmin and sqrts<=xmax) :
desthisto.addPoint(h.points()[i])
elif(type(desthisto)==yoda.core.Profile1D) :
for sqrts, h in sorted(sourcehistosbysqrts.items()) :
step = 0.001
for i in range(0,h.numBins()) :
xmin = min(h.bins()[i].xMin(),h.bins()[i].xMid()-step)
xmax = max(h.bins()[i].xMax(),h.bins()[i].xMid()+step)
if(sqrts>=xmin and sqrts<=xmax) :
desthisto.bins()[i] += h.bins()[i]
break
else :
logging.error("Unknown analysis object" + desthisto.path)
sys.exit(1)
def merge(hpath):
global inhistos
global outhistos
try:
fillAbove(outhistos[hpath], inhistos[hpath])
except:
pass
def useOne(hpath, sqrts):
global inhistos
global outhistos
try:
outhistos[hpath] = inhistos[hpath][float(sqrts)]
except:
try:
outhistos[hpath] = inhistos[hpath][sqrts]
except:
pass
def average(hpath, sqrts1,sqrts2):
global inhistos
global outhistos
outhistos[hpath] = inhistos[hpath][float(sqrts1)]+inhistos[hpath][float(sqrts2)]
outhistos[hpath].setPath(hpath)
outhistos[hpath].scaleW(0.5)
if __name__ == "__main__":
import logging
from optparse import OptionParser, OptionGroup
parser = OptionParser(usage="%prog name")
verbgroup = OptionGroup(parser, "Verbosity control")
verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL",
default=logging.INFO, help="print debug (very verbose) messages")
verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL",
default=logging.INFO, help="be very quiet")
parser.add_option_group(verbgroup)
parser.add_option("--with-gg",
action='store_true' ,
dest="gg",
default=False,
help="Include gg analyses")
parser.add_option("--without-gg",
action='store_false',
dest="gg",
default=False,
help="Don\'t include gg analyses")
parser.add_option("--with-decay",
action='store_true' ,
dest="decay",
default=False,
help="Include decay analyses")
parser.add_option("--without-decay",
action='store_false',
dest="decay",
default=False,
help="Don\'t include decay analyses")
+ parser.add_option("--with-WW",
+ action='store_true' ,
+ dest="WW",
+ default=False,
+ help="Include WW analyses")
+ parser.add_option("--without-WW",
+ action='store_false',
+ dest="WW",
+ default=False,
+ help="Don\'t include WW analyses")
(opts, args) = parser.parse_args()
logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s")
## Check args
if len(args) < 1:
logging.error("Must specify at least the name of the files")
sys.exit(1)
#######################################
yodafiles=["130","130.1","133","136","136.1","177","192",
"194.4","196","202","205","206","206.2","207","91" ,"91-nopi" ,\
"161","161.3","182.8","183","197","35" ,"36.2","172","172.3",\
- "188.6","189","200","200.2","44","14","14.8","21.5","22","25","10",\
+ "188.6","189","200","200.2","44","14","14.8","21.5","22","22.5","25","10",\
"12.8","26.8","48.0","93.0",\
- "12","13","17","27.6","27.7","29","30.2","30.3","34.5",\
- "30.7","30.8","30","31.2","31.3","31.6","34","34.8","42.1","43.5","43.6","50","52","53.3",\
+ "12","13","17","27.6","27.7","29","30.2","30.3","30.5","34.5",\
+ "30.7","30.8","30","31.2","31.3","31.6","34","34.8","41.5","42.1","43.5","43.6","50","52","53.3",\
"55","55.3","56","57","58","59.5","60.8","60","61.4","7.7",
"9.4","45","65.4","66","75.7","76","41","42.6","82","85","2.2","2.6","3.0","3.2","4.6","4.8",
- "5.8","6.2","6.6","7.0","7.4","3.63","4.03","4.17","4.3",
+ "5.8","6.2","6.5","6.6","7.0","7.4","3.63","4.03","4.17","4.3",
"4.41","5.0","5.2","4.5","8.8","9.27","9.46","9.51","10.52","10.52-sym","10.54","10.58",
"10.6","10.45","10.47"]
# add gg if needed
if(opts.gg) :
yodafiles += ["10.5-gg","12.8-gg","16.86-gg","26.8-gg",\
"35.44-gg","97.0-gg","11.96-gg","13.96-gg",\
"21.84-gg","28.48-gg","48.0-gg"]
# add decays if needed
if(opts.decay) :
- yodafiles += ["Upsilon","Upsilon2","Upsilon3","Upsilon4","Upsilon4-asym",
+ yodafiles += ["Upsilon","Upsilon2","Upsilon3","Upsilon4","Upsilon5","Upsilon4-asym",
"Tau","Phi","Lambdac","Omega-Meson",
"Omega-Baryon","Eta","Xi0","Xic0","Xicp",
"Omegac0","Xim","Ds","Bc","Etac","JPsi","Psi2S","Psi2S-All","Psi3770"]
+# WW production
+if(opts.WW) :
+ yodafiles+=["183-WW","189-WW"]
## Get histos
inhistos = {}
outhistos={}
for f in yodafiles:
file = "Rivet-%s-%s.yoda" % (args[0], f)
if(file.find("Tau")>0) :
sqrts=10.58
elif(file.find("Upsilon4")>0) :
sqrts="U4"
elif(file.find("Upsilon2")>0) :
sqrts="U2"
elif(file.find("Upsilon3")>0) :
sqrts="U3"
elif(file.find("Upsilon")>0) :
sqrts="U1"
elif(file.find("Phi")>0) :
sqrts="phi"
elif(file.find("Omega-Meson")>0) :
sqrts="omega"
elif(file.find("JPsi")>0) :
sqrts="psi"
elif(file.find("Psi2S")>0) :
sqrts="psi2s"
elif(file.find("Psi3770")>0) :
sqrts="psi1d"
elif(file.find("Ds")>0) :
sqrts="Ds"
elif(file.find("Bc")>0) :
sqrts="Bc"
elif(file.find("Lambdac")>0 or file.find("Xic0")>0 or
file.find("Omega")>0 or file.find("Xi0")>0 or
file.find("Xim")>0 or file.find("Xicp")>0 or
file.find("Eta")>0) :
sqrts="baryon"
else :
sqrts=float(f.split("-")[0])
if not os.access(file, os.R_OK):
logging.error("%s cannot be read" % file)
continue
try:
aos = yoda.read(file)
except:
logging.error("%s cannot be parsed as yoda" % file)
continue
## Get histos from this YODA file
for aopath, ao in aos.items() :
if("RAW" in aopath or "/_" in aopath) :continue
# plots which neede merging/selecting
if(aopath.find("4300807")>0 or aopath.find("6132243")>0 or
aopath.find("5765862")>0 or aopath.find("3612880")>0 or
aopath.find("4328825")>0 or aopath.find("5361494")>0 or
aopath.find("2148048")>0 or aopath.find("295160" )>0 or
aopath.find("190818" )>0 or aopath.find("154270" )>0 or
aopath.find("277658" )>0 or aopath.find("143691" )>0 or
aopath.find("6265367")>0 or aopath.find("6895344")>0 or
aopath.find("6181155")>0 or aopath.find("2789213")>0 or
aopath.find("2669951")>0 or aopath.find("278933" )>0 or
aopath.find("276860" )>0 or aopath.find("251097" )>0 or
aopath.find("262551" )>0 or aopath.find("262415" )>0 or
aopath.find("165122" )>0 or aopath.find("118873" )>0 or
aopath.find("177174" )>0 or aopath.find("284251" )>0 or
aopath.find("191161" )>0 or aopath.find("1422780")>0 or
aopath.find("132410" )>0 or "JADE_1979_I142874" in aopath or
+ "I195333" in aopath or "I297905" in aopath or
+ "I526164" in aopath or "I178416" in aopath or
"LENA_1981_I164397" in aopath or "ARGUS_1991_I315059" in aopath or
"TASSO_1989_I266893" in aopath or "CLEO_1985_I205668" in aopath or
"BABAR_2014_I1286317" in aopath or
("OPAL_2000_I513476" in aopath and ("d14" in aopath or "d20" in aopath )) or
(aopath.find("MULTIPLICITIES")>0 and aopath.find("Upsilon_4S")<0)) :
+ if "526164" in aopath :
+ if ("d01" in aopath or "d02" in aopath or "d16" in aopath) :
+ if "WW" in f : continue
+ else :
+ if "WW" not in f : continue
+
if aopath not in inhistos:
inhistos[aopath] = {}
tmpE = inhistos[aopath]
sqrttemp=sqrts
if(aopath.find("2669951")>0 and aopath.find("d01")>0 and
sqrts==10.45) :
sqrts=9.9
if sqrts not in tmpE:
tmpE[sqrts] = ao
else:
raise Exception("A set with sqrts = %s already exists" % ( sqrts))
sqrts=sqrttemp
elif(aopath.find("OPAL_2004_I648738")>=0) :
if(file.find("gg")>=0) :
if(aopath.find("y03")>=0) :
outhistos[aopath] = ao
else :
if(aopath.find("y03")<0) :
outhistos[aopath] = ao
elif("MARKI_1975_I100733" in aopath) :
if "d03" in aopath :
outhistos[aopath] = ao
elif("A2_2017_I1486671" in aopath or
"NA60_2016_I1452485" in aopath ) :
if("Eta" in file) :
if "d01" in aopath : outhistos[aopath] = ao
elif("Omega" in file) :
if "d02" in aopath : outhistos[aopath] = ao
else :
outhistos[aopath] = ao
elif("ARGUS_1992_I319102" in aopath) :
if(("d02" in aopath or "d04" in aopath) and sqrts==10.47) :
outhistos[aopath] = ao
elif(("d03"in aopath or "d05" in aopath) and sqrts=="U4") :
outhistos[aopath] = ao
elif("MC_OmegaPhia1_3Pion_Decay" in aopath) :
if("_1" in aopath and "Omega" in file) :
outhistos[aopath] = ao
elif("_2" in aopath and "Phi" in file) :
outhistos[aopath] = ao
elif("BABAR_2006_I719581" in aopath) :
if("d02" in aopath and "Omega" in file) :
outhistos[aopath] = ao
elif("d01" in aopath and "Xi" in file) :
outhistos[aopath] = ao
elif("BABAR_2002_I582184" in aopath) :
if(("d02" in aopath or "d05" in aopath ) and "Upsilon" in file) :
outhistos[aopath] = ao
elif( not ("d02" in aopath or "d05" in aopath ) and sqrts==10.6) :
outhistos[aopath] = ao
elif(aopath=="/BABAR_2007_I746745/d01-x01-y01") :
htemp = aos["/RAW/BABAR_2007_I746745/d01-x01-y01"]
htemp.scaleW(aos["/_XSEC"].points()[0].x()/aos["/_EVTCOUNT"].val())
htemp.setPath("/BABAR_2007_I746745/d01-x01-y01")
if "/BABAR_2007_I746745/d01-x01-y01" in outhistos :
htemp2=htemp+outhistos["/BABAR_2007_I746745/d01-x01-y01"]
htemp2.setPath("/BABAR_2007_I746745/d01-x01-y01")
outhistos["/BABAR_2007_I746745/d01-x01-y01"]=htemp2
else :
outhistos["/BABAR_2007_I746745/d01-x01-y01"]=htemp
elif(aopath=="/BABAR_2007_I722622/d03-x01-y01" or
aopath=="/BABAR_2007_I722622/d03-x01-y02" or
aopath=="/BABAR_2007_I722622/d04-x01-y01") :
htemp = aos["/RAW"+aopath]
htemp.scaleW(aos["/_XSEC"].points()[0].x()/aos["/_EVTCOUNT"].val())
htemp.setPath(aopath)
if aopath in outhistos :
htemp2=htemp+outhistos[aopath]
htemp2.setPath(aopath)
outhistos[aopath]=htemp2
else :
outhistos[aopath]=htemp
elif "BELLE_2017_I1610301" in aopath :
if "Upsilon2" in file and "y01" in aopath:
outhistos[aopath] = ao
elif "Upsilon3" in file and "y02" in aopath:
outhistos[aopath] = ao
elif "Upsilon4" in file and ("y03" in aopath or "y04" in aopath) :
outhistos[aopath] = ao
+ elif "FOCUS_2003_I635446" in aopath :
+ if "Ds" in file :
+ if "d01" in aopath or "dalitz1" in aopath :
+ outhistos[aopath] = ao
+ else :
+ if "d02" in aopath or "dalitz2" in aopath :
+ outhistos[aopath] = ao
+ elif "FOCUS_2004_I654030" in aopath :
+ if "Ds" in file :
+ if "d02" in aopath or "dalitz_2" in aopath :
+ outhistos[aopath] = ao
+ else :
+ if "d01" in aopath or "dalitz_1" in aopath :
+ outhistos[aopath] = ao
else:
outhistos[aopath] = ao
# Make empty output histos if needed
for hpath,hsets in inhistos.items():
if( hpath.find("4300807")>0 or hpath.find("6132243")>0 or
hpath.find("5765862")>0 or hpath.find("295160" )>0 or
hpath.find("4328825")>0 or hpath.find("5361494")>0 or
hpath.find("190818" )>0 or hpath.find("154270" )>0 or
hpath.find("277658" )>0 or hpath.find("2669951")>0 or
hpath.find("276860" )>0 or hpath.find("165122" )>0 or
hpath.find("118873" )>0 or hpath.find("143691" )>0 or
hpath.find("284251" )>0 or hpath.find("191161" )>0 or
hpath.find("1422780")>0 or hpath.find("132410" )>0 or
+ ("526164" in hpath and ("d01" in hpath or "d02" in hpath or "d03" in hpath) ) or
+ ("195333" in hpath and "d04" in hpath) or
"OPAL_2000_I513476" in hpath or
"JADE_1979_I142874" in hpath or
"CLEO_1985_I205668" in hpath or
"BABAR_2014_I1286317" in hpath or
"LENA_1981_I164397" in hpath):
if(hpath=="/PLUTO_1981_I165122/d01-x01-y01" or
hpath=="/PLUTO_1981_I165122/d03-x01-y01" ) : continue
title=""
path=""
histo = list(hsets.values())[0]
if hasattr(histo, 'title'):
title=histo.title()
if hasattr(histo, 'path'):
path=histo.path()
if(type(histo)==yoda.core.Scatter2D) :
outhistos[hpath] = yoda.core.Scatter2D(path,title)
elif(type(histo)==yoda.core.Profile1D) :
outhistos[hpath] = yoda.core.Profile1D(path,title)
for i in range(0,histo.numBins()) :
outhistos[hpath].addBin(histo.bins()[i].xMin(),
histo.bins()[i].xMax())
elif(type(histo)==yoda.core.Histo1D) :
outhistos[hpath] = yoda.core.Histo1D(path,title)
for i in range(0,histo.numBins()) :
outhistos[hpath].addBin(histo.bins()[i].xMin(),
histo.bins()[i].xMax())
else :
logging.error("Histogram %s is of unknown type" % hpath)
sys.exit(1)
# tasso
-useOne("/TASSO_1990_S2148048/d06-x01-y01","14")
-useOne("/TASSO_1990_S2148048/d07-x01-y01","14")
-useOne("/TASSO_1990_S2148048/d08-x01-y01","14")
-useOne("/TASSO_1990_S2148048/d06-x01-y02","22")
-useOne("/TASSO_1990_S2148048/d07-x01-y02","22")
-useOne("/TASSO_1990_S2148048/d08-x01-y02","22")
-useOne("/TASSO_1990_S2148048/d06-x01-y03","35")
-useOne("/TASSO_1990_S2148048/d07-x01-y03","35")
-useOne("/TASSO_1990_S2148048/d08-x01-y03","35")
-useOne("/TASSO_1990_S2148048/d06-x01-y04","44")
-useOne("/TASSO_1990_S2148048/d07-x01-y04","44")
-useOne("/TASSO_1990_S2148048/d08-x01-y04","44")
+eTemp=["14","22","35","44"]
+for ih in range(2,9) :
+ for iy in range(0,4) :
+ useOne("/TASSO_1990_S2148048/d0%s-x01-y0%s" % (ih,iy+1),eTemp[iy])
# jade
useOne("/JADE_1998_S3612880/d02-x01-y01","44")
useOne("/JADE_1998_S3612880/d03-x01-y01","44")
useOne("/JADE_1998_S3612880/d04-x01-y01","44")
useOne("/JADE_1998_S3612880/d05-x01-y01","44")
useOne("/JADE_1998_S3612880/d06-x01-y01","35")
useOne("/JADE_1998_S3612880/d07-x01-y01","35")
useOne("/JADE_1998_S3612880/d08-x01-y01","35")
useOne("/JADE_1998_S3612880/d09-x01-y01","35")
useOne("/JADE_1998_S3612880/d10-x01-y01","44")
useOne("/JADE_1998_S3612880/d11-x01-y01","35")
useOne("/JADE_1998_S3612880/d12-x01-y01","22")
# opal/jade
useOne("/JADE_OPAL_2000_S4300807/d07-x01-y01","35")
useOne("/JADE_OPAL_2000_S4300807/d07-x01-y02","35")
useOne("/JADE_OPAL_2000_S4300807/d07-x01-y03","35")
useOne("/JADE_OPAL_2000_S4300807/d07-x01-y04","35")
useOne("/JADE_OPAL_2000_S4300807/d07-x01-y05","35")
useOne("/JADE_OPAL_2000_S4300807/d08-x01-y01","44")
useOne("/JADE_OPAL_2000_S4300807/d08-x01-y02","44")
useOne("/JADE_OPAL_2000_S4300807/d08-x01-y03","44")
useOne("/JADE_OPAL_2000_S4300807/d08-x01-y04","44")
useOne("/JADE_OPAL_2000_S4300807/d08-x01-y05","44")
useOne("/JADE_OPAL_2000_S4300807/d09-x01-y01","91")
useOne("/JADE_OPAL_2000_S4300807/d09-x01-y02","91")
useOne("/JADE_OPAL_2000_S4300807/d09-x01-y03","91")
useOne("/JADE_OPAL_2000_S4300807/d09-x01-y04","91")
useOne("/JADE_OPAL_2000_S4300807/d09-x01-y05","91")
useOne("/JADE_OPAL_2000_S4300807/d10-x01-y01","133")
useOne("/JADE_OPAL_2000_S4300807/d10-x01-y02","133")
useOne("/JADE_OPAL_2000_S4300807/d10-x01-y03","133")
useOne("/JADE_OPAL_2000_S4300807/d10-x01-y04","133")
useOne("/JADE_OPAL_2000_S4300807/d10-x01-y05","133")
useOne("/JADE_OPAL_2000_S4300807/d11-x01-y01","161")
useOne("/JADE_OPAL_2000_S4300807/d11-x01-y02","161")
useOne("/JADE_OPAL_2000_S4300807/d11-x01-y03","161")
useOne("/JADE_OPAL_2000_S4300807/d11-x01-y04","161")
useOne("/JADE_OPAL_2000_S4300807/d11-x01-y05","161")
useOne("/JADE_OPAL_2000_S4300807/d12-x01-y01","172")
useOne("/JADE_OPAL_2000_S4300807/d12-x01-y02","172")
useOne("/JADE_OPAL_2000_S4300807/d12-x01-y03","172")
useOne("/JADE_OPAL_2000_S4300807/d12-x01-y04","172")
useOne("/JADE_OPAL_2000_S4300807/d12-x01-y05","172")
useOne("/JADE_OPAL_2000_S4300807/d13-x01-y01","183")
useOne("/JADE_OPAL_2000_S4300807/d13-x01-y02","183")
useOne("/JADE_OPAL_2000_S4300807/d13-x01-y03","183")
useOne("/JADE_OPAL_2000_S4300807/d13-x01-y04","183")
useOne("/JADE_OPAL_2000_S4300807/d13-x01-y05","183")
useOne("/JADE_OPAL_2000_S4300807/d14-x01-y01","189")
useOne("/JADE_OPAL_2000_S4300807/d14-x01-y02","189")
useOne("/JADE_OPAL_2000_S4300807/d14-x01-y03","189")
useOne("/JADE_OPAL_2000_S4300807/d14-x01-y04","189")
useOne("/JADE_OPAL_2000_S4300807/d14-x01-y05","189")
useOne("/JADE_OPAL_2000_S4300807/d16-x01-y01","35")
useOne("/JADE_OPAL_2000_S4300807/d16-x01-y02","35")
useOne("/JADE_OPAL_2000_S4300807/d16-x01-y03","35")
useOne("/JADE_OPAL_2000_S4300807/d16-x01-y04","35")
useOne("/JADE_OPAL_2000_S4300807/d16-x01-y05","35")
useOne("/JADE_OPAL_2000_S4300807/d17-x01-y01","44")
useOne("/JADE_OPAL_2000_S4300807/d17-x01-y02","44")
useOne("/JADE_OPAL_2000_S4300807/d17-x01-y03","44")
useOne("/JADE_OPAL_2000_S4300807/d17-x01-y04","44")
useOne("/JADE_OPAL_2000_S4300807/d17-x01-y05","44")
useOne("/JADE_OPAL_2000_S4300807/d18-x01-y01","91")
useOne("/JADE_OPAL_2000_S4300807/d18-x01-y02","91")
useOne("/JADE_OPAL_2000_S4300807/d18-x01-y03","91")
useOne("/JADE_OPAL_2000_S4300807/d18-x01-y04","91")
useOne("/JADE_OPAL_2000_S4300807/d18-x01-y05","91")
useOne("/JADE_OPAL_2000_S4300807/d19-x01-y01","133")
useOne("/JADE_OPAL_2000_S4300807/d19-x01-y02","133")
useOne("/JADE_OPAL_2000_S4300807/d19-x01-y03","133")
useOne("/JADE_OPAL_2000_S4300807/d19-x01-y04","133")
useOne("/JADE_OPAL_2000_S4300807/d19-x01-y05","133")
useOne("/JADE_OPAL_2000_S4300807/d20-x01-y01","161")
useOne("/JADE_OPAL_2000_S4300807/d20-x01-y02","161")
useOne("/JADE_OPAL_2000_S4300807/d20-x01-y03","161")
useOne("/JADE_OPAL_2000_S4300807/d20-x01-y04","161")
useOne("/JADE_OPAL_2000_S4300807/d20-x01-y05","161")
useOne("/JADE_OPAL_2000_S4300807/d21-x01-y01","172")
useOne("/JADE_OPAL_2000_S4300807/d21-x01-y02","172")
useOne("/JADE_OPAL_2000_S4300807/d21-x01-y03","172")
useOne("/JADE_OPAL_2000_S4300807/d21-x01-y04","172")
useOne("/JADE_OPAL_2000_S4300807/d21-x01-y05","172")
useOne("/JADE_OPAL_2000_S4300807/d22-x01-y01","183")
useOne("/JADE_OPAL_2000_S4300807/d22-x01-y02","183")
useOne("/JADE_OPAL_2000_S4300807/d22-x01-y03","183")
useOne("/JADE_OPAL_2000_S4300807/d22-x01-y04","183")
useOne("/JADE_OPAL_2000_S4300807/d22-x01-y05","183")
useOne("/JADE_OPAL_2000_S4300807/d23-x01-y01","189")
useOne("/JADE_OPAL_2000_S4300807/d23-x01-y02","189")
useOne("/JADE_OPAL_2000_S4300807/d23-x01-y03","189")
useOne("/JADE_OPAL_2000_S4300807/d23-x01-y04","189")
useOne("/JADE_OPAL_2000_S4300807/d23-x01-y05","189")
useOne("/JADE_OPAL_2000_S4300807/d24-x01-y01","35")
useOne("/JADE_OPAL_2000_S4300807/d24-x01-y02","35")
useOne("/JADE_OPAL_2000_S4300807/d24-x01-y03","35")
useOne("/JADE_OPAL_2000_S4300807/d24-x01-y04","35")
useOne("/JADE_OPAL_2000_S4300807/d25-x01-y01","44")
useOne("/JADE_OPAL_2000_S4300807/d25-x01-y02","44")
useOne("/JADE_OPAL_2000_S4300807/d25-x01-y03","44")
useOne("/JADE_OPAL_2000_S4300807/d25-x01-y04","44")
useOne("/JADE_OPAL_2000_S4300807/d26-x01-y01","91")
useOne("/JADE_OPAL_2000_S4300807/d26-x01-y02","91")
useOne("/JADE_OPAL_2000_S4300807/d26-x01-y03","91")
useOne("/JADE_OPAL_2000_S4300807/d26-x01-y04","91")
useOne("/JADE_OPAL_2000_S4300807/d27-x01-y01","133")
useOne("/JADE_OPAL_2000_S4300807/d27-x01-y02","133")
useOne("/JADE_OPAL_2000_S4300807/d27-x01-y03","133")
useOne("/JADE_OPAL_2000_S4300807/d27-x01-y04","133")
useOne("/JADE_OPAL_2000_S4300807/d28-x01-y01","161")
useOne("/JADE_OPAL_2000_S4300807/d28-x01-y02","161")
useOne("/JADE_OPAL_2000_S4300807/d28-x01-y03","161")
useOne("/JADE_OPAL_2000_S4300807/d28-x01-y04","161")
useOne("/JADE_OPAL_2000_S4300807/d29-x01-y01","172")
useOne("/JADE_OPAL_2000_S4300807/d29-x01-y02","172")
useOne("/JADE_OPAL_2000_S4300807/d29-x01-y03","172")
useOne("/JADE_OPAL_2000_S4300807/d29-x01-y04","172")
useOne("/JADE_OPAL_2000_S4300807/d30-x01-y01","183")
useOne("/JADE_OPAL_2000_S4300807/d30-x01-y02","183")
useOne("/JADE_OPAL_2000_S4300807/d30-x01-y03","183")
useOne("/JADE_OPAL_2000_S4300807/d30-x01-y04","183")
useOne("/JADE_OPAL_2000_S4300807/d31-x01-y01","189")
useOne("/JADE_OPAL_2000_S4300807/d31-x01-y02","189")
useOne("/JADE_OPAL_2000_S4300807/d31-x01-y03","189")
useOne("/JADE_OPAL_2000_S4300807/d31-x01-y04","189")
useOne("/OPAL_2004_S6132243/d01-x01-y01","91")
useOne("/OPAL_2004_S6132243/d01-x01-y02","133")
useOne("/OPAL_2004_S6132243/d01-x01-y03","177")
useOne("/OPAL_2004_S6132243/d01-x01-y04","197")
useOne("/OPAL_2004_S6132243/d02-x01-y01","91")
useOne("/OPAL_2004_S6132243/d02-x01-y02","133")
useOne("/OPAL_2004_S6132243/d02-x01-y03","177")
useOne("/OPAL_2004_S6132243/d02-x01-y04","197")
useOne("/OPAL_2004_S6132243/d03-x01-y01","91")
useOne("/OPAL_2004_S6132243/d03-x01-y02","133")
useOne("/OPAL_2004_S6132243/d03-x01-y03","177")
useOne("/OPAL_2004_S6132243/d03-x01-y04","197")
useOne("/OPAL_2004_S6132243/d04-x01-y01","91")
useOne("/OPAL_2004_S6132243/d04-x01-y02","133")
useOne("/OPAL_2004_S6132243/d04-x01-y03","177")
useOne("/OPAL_2004_S6132243/d04-x01-y04","197")
useOne("/OPAL_2004_S6132243/d05-x01-y01","91")
useOne("/OPAL_2004_S6132243/d05-x01-y02","133")
useOne("/OPAL_2004_S6132243/d05-x01-y03","177")
useOne("/OPAL_2004_S6132243/d05-x01-y04","197")
useOne("/OPAL_2004_S6132243/d06-x01-y01","91")
useOne("/OPAL_2004_S6132243/d06-x01-y02","133")
useOne("/OPAL_2004_S6132243/d06-x01-y03","177")
useOne("/OPAL_2004_S6132243/d06-x01-y04","197")
useOne("/OPAL_2004_S6132243/d07-x01-y01","91")
useOne("/OPAL_2004_S6132243/d07-x01-y02","133")
useOne("/OPAL_2004_S6132243/d07-x01-y03","177")
useOne("/OPAL_2004_S6132243/d07-x01-y04","197")
useOne("/OPAL_2004_S6132243/d08-x01-y01","91")
useOne("/OPAL_2004_S6132243/d08-x01-y02","133")
useOne("/OPAL_2004_S6132243/d08-x01-y03","177")
useOne("/OPAL_2004_S6132243/d08-x01-y04","197")
useOne("/OPAL_2004_S6132243/d09-x01-y01","91")
useOne("/OPAL_2004_S6132243/d09-x01-y02","133")
useOne("/OPAL_2004_S6132243/d09-x01-y03","177")
useOne("/OPAL_2004_S6132243/d09-x01-y04","197")
useOne("/OPAL_2004_S6132243/d10-x01-y01","91")
useOne("/OPAL_2004_S6132243/d10-x01-y02","133")
useOne("/OPAL_2004_S6132243/d10-x01-y03","177")
useOne("/OPAL_2004_S6132243/d10-x01-y04","197")
useOne("/OPAL_2004_S6132243/d11-x01-y01","91")
useOne("/OPAL_2004_S6132243/d11-x01-y02","133")
useOne("/OPAL_2004_S6132243/d11-x01-y03","177")
useOne("/OPAL_2004_S6132243/d11-x01-y04","197")
useOne("/OPAL_2004_S6132243/d12-x01-y01","91")
useOne("/OPAL_2004_S6132243/d12-x01-y02","133")
useOne("/OPAL_2004_S6132243/d12-x01-y03","177")
useOne("/OPAL_2004_S6132243/d12-x01-y04","197")
useOne("/OPAL_2004_S6132243/d13-x01-y01","91")
useOne("/OPAL_2004_S6132243/d13-x01-y02","133")
useOne("/OPAL_2004_S6132243/d13-x01-y03","177")
useOne("/OPAL_2004_S6132243/d13-x01-y04","197")
useOne("/OPAL_2004_S6132243/d14-x01-y01","91")
useOne("/OPAL_2004_S6132243/d14-x01-y02","133")
useOne("/OPAL_2004_S6132243/d14-x01-y03","177")
useOne("/OPAL_2004_S6132243/d14-x01-y04","197")
useOne("/OPAL_2004_S6132243/d15-x01-y01","91")
useOne("/OPAL_2004_S6132243/d15-x01-y02","133")
useOne("/OPAL_2004_S6132243/d15-x01-y03","177")
useOne("/OPAL_2004_S6132243/d15-x01-y04","197")
useOne("/OPAL_2004_S6132243/d16-x01-y01","91")
useOne("/OPAL_2004_S6132243/d16-x01-y02","133")
useOne("/OPAL_2004_S6132243/d16-x01-y03","177")
useOne("/OPAL_2004_S6132243/d16-x01-y04","197")
useOne("/OPAL_2004_S6132243/d17-x01-y01","91")
useOne("/OPAL_2004_S6132243/d17-x01-y02","133")
useOne("/OPAL_2004_S6132243/d17-x01-y03","177")
useOne("/OPAL_2004_S6132243/d17-x01-y04","197")
useOne("/OPAL_2004_S6132243/d18-x01-y01","91")
useOne("/OPAL_2004_S6132243/d18-x01-y02","133")
useOne("/OPAL_2004_S6132243/d18-x01-y03","177")
useOne("/OPAL_2004_S6132243/d18-x01-y04","197")
useOne("/OPAL_2004_S6132243/d19-x01-y01","91")
useOne("/OPAL_2004_S6132243/d19-x01-y02","133")
useOne("/OPAL_2004_S6132243/d19-x01-y03","177")
useOne("/OPAL_2004_S6132243/d19-x01-y04","197")
useOne("/OPAL_2004_S6132243/d20-x01-y01","91")
useOne("/OPAL_2004_S6132243/d20-x01-y02","133")
useOne("/OPAL_2004_S6132243/d20-x01-y03","177")
useOne("/OPAL_2004_S6132243/d20-x01-y04","197")
useOne("/OPAL_2004_S6132243/d21-x01-y01","91")
useOne("/OPAL_2004_S6132243/d21-x01-y02","133")
useOne("/OPAL_2004_S6132243/d21-x01-y03","177")
useOne("/OPAL_2004_S6132243/d21-x01-y04","197")
useOne("/OPAL_2004_S6132243/d22-x01-y01","91")
useOne("/OPAL_2004_S6132243/d22-x01-y02","133")
useOne("/OPAL_2004_S6132243/d22-x01-y03","177")
useOne("/OPAL_2004_S6132243/d22-x01-y04","197")
useOne("/OPAL_2004_S6132243/d23-x01-y01","91")
useOne("/OPAL_2004_S6132243/d23-x01-y02","133")
useOne("/OPAL_2004_S6132243/d23-x01-y03","177")
useOne("/OPAL_2004_S6132243/d23-x01-y04","197")
useOne("/OPAL_2004_S6132243/d24-x01-y01","91")
useOne("/OPAL_2004_S6132243/d24-x01-y02","133")
useOne("/OPAL_2004_S6132243/d24-x01-y03","177")
useOne("/OPAL_2004_S6132243/d24-x01-y04","197")
useOne("/OPAL_2004_S6132243/d25-x01-y01","91")
useOne("/OPAL_2004_S6132243/d25-x01-y02","133")
useOne("/OPAL_2004_S6132243/d25-x01-y03","177")
useOne("/OPAL_2004_S6132243/d25-x01-y04","197")
useOne("/OPAL_2004_S6132243/d26-x01-y01","91")
useOne("/OPAL_2004_S6132243/d26-x01-y02","133")
useOne("/OPAL_2004_S6132243/d26-x01-y03","177")
useOne("/OPAL_2004_S6132243/d26-x01-y04","197")
merge( "/OPAL_2002_S5361494/d01-x01-y01")
merge( "/OPAL_2002_S5361494/d01-x01-y02")
merge( "/OPAL_2002_S5361494/d01-x01-y03")
merge( "/OPAL_2002_S5361494/d01-x01-y04")
merge("/DELPHI_2000_S4328825/d01-x01-y01")
merge("/DELPHI_2000_S4328825/d01-x01-y02")
merge("/DELPHI_2000_S4328825/d01-x01-y03")
merge("/DELPHI_2000_S4328825/d01-x01-y04")
merge("/ALEPH_2004_S5765862/d01-x01-y01")
useOne("/ALEPH_2004_S5765862/d02-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d03-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d04-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d05-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d06-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d07-x01-y01","196")
useOne("/ALEPH_2004_S5765862/d08-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d09-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d11-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d12-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d13-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d14-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d15-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d16-x01-y01","196")
useOne("/ALEPH_2004_S5765862/d17-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d18-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d19-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d20-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d21-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d22-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d23-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d24-x01-y01","196")
useOne("/ALEPH_2004_S5765862/d25-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d26-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d27-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d28-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d29-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d30-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d31-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d32-x01-y01","196")
useOne("/ALEPH_2004_S5765862/d33-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d34-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d35-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d36-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d37-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d38-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d39-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d40-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d41-x01-y01","196")
useOne("/ALEPH_2004_S5765862/d42-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d43-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d44-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d45-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d46-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d47-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d48-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d49-x01-y01","196")
useOne("/ALEPH_2004_S5765862/d50-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d51-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d54-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d55-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d56-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d57-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d58-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d59-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d60-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d61-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d62-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d63-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d64-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d65-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d66-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d67-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d68-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d69-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d70-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d71-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d72-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d73-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d74-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d75-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d76-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d77-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d78-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d79-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d80-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d81-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d82-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d83-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d84-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d85-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d86-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d87-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d88-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d89-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d90-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d91-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d92-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d93-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d94-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d95-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d96-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d97-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d98-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d99-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d100-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d101-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d102-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d103-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d104-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d105-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d106-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d107-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d108-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d109-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d110-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d111-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d112-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d113-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d114-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d115-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d116-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d117-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d118-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d119-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d120-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d121-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d122-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d123-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d124-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d125-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d126-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d127-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d128-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d129-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d130-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d131-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d132-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d133-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d134-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d135-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d136-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d137-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d138-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d139-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d140-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d141-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d142-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d143-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d144-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d145-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d146-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d147-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d148-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d149-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d150-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d151-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d152-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d153-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d154-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d155-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d156-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d157-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d158-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d159-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d160-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d161-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d162-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d163-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d164-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d165-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d166-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d167-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d168-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d169-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d170-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d172-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d173-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d174-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d175-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d176-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d177-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d178-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d179-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d180-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d181-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d182-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d183-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d184-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d185-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d186-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d187-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d188-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d189-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d190-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d191-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d192-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d193-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d194-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d195-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d196-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d197-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d198-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d199-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d200-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d201-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d202-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d203-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d204-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d205-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d206-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d207-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d208-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d209-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d210-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d211-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d212-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d213-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d214-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d215-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d216-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d217-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d218-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d219-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d220-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d221-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d222-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d223-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d224-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d225-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d226-x01-y01","206")
useOne("/ALEPH_2004_S5765862/d227-x01-y01","91")
useOne("/ALEPH_2004_S5765862/d228-x01-y01","133")
useOne("/ALEPH_2004_S5765862/d229-x01-y01","161")
useOne("/ALEPH_2004_S5765862/d230-x01-y01","172")
useOne("/ALEPH_2004_S5765862/d231-x01-y01","183")
useOne("/ALEPH_2004_S5765862/d232-x01-y01","189")
useOne("/ALEPH_2004_S5765862/d233-x01-y01","200")
useOne("/ALEPH_2004_S5765862/d234-x01-y01","206")
# hadron multiplicities
useOne("/PDG_HADRON_MULTIPLICITIES/d01-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d02-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d03-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d04-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d05-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d06-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d07-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d08-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d09-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d13-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d15-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d17-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d18-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d19-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d20-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d21-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d22-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d23-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d25-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d31-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d38-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d39-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d40-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d44-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d45-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d46-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d47-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d48-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d49-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d50-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d51-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d53-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d54-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES/d01-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d02-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d03-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d04-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d05-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d06-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d07-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d08-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d09-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d13-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d15-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d18-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d19-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d20-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d21-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d22-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d31-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d33-x01-y01","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d34-x01-y01","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d38-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d39-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d44-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d46-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d47-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d48-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d50-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d51-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES/d01-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d02-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d03-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d04-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d05-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d06-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d07-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d08-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d09-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d10-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d11-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d12-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d13-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d14-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d15-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d16-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d17-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d18-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d19-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d20-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d21-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d23-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d24-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d25-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d26-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d27-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d28-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d29-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d30-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d31-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d32-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d34-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d35-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d36-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d37-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d38-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d39-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d40-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d41-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d42-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d43-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d44-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d45-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d46-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d47-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d48-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d49-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d50-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d51-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d52-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d54-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES/d01-x01-y04","177")
useOne("/PDG_HADRON_MULTIPLICITIES/d03-x01-y04","177")
useOne("/PDG_HADRON_MULTIPLICITIES/d04-x01-y04","177")
useOne("/PDG_HADRON_MULTIPLICITIES/d38-x01-y04","177")
useOne("/PDG_HADRON_MULTIPLICITIES/d39-x01-y04","177")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d02-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d05-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d06-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d07-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d08-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d09-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d13-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d15-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d17-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d18-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d19-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d20-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d21-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d22-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d23-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d25-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d31-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y01","10" )
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d40-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d44-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d45-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d46-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d47-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d48-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d49-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d50-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d51-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d53-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d54-x01-y01","10")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d02-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d05-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d06-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d07-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d08-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d09-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d13-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d15-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d18-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d19-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d20-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d21-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d22-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d31-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d33-x01-y01","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d34-x01-y01","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d44-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d46-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d47-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d48-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d50-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d51-x01-y02","35")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d02-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d05-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d06-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d07-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d08-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d09-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d10-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d11-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d12-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d13-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d14-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d15-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d16-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d17-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d18-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d19-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d20-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d21-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d23-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d24-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d25-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d26-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d27-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d28-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d29-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d30-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d31-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d32-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d34-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d35-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d36-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d37-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d40-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d41-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d42-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d43-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d44-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d45-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d46-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d47-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d48-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d49-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d50-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d51-x01-y03","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d52-x01-y01","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d54-x01-y02","91")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y04","177")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y04","177")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y04","177")
useOne("/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y04","177")
# AMY analysis
useOne("/AMY_1990_I295160/d01-x01-y01","50")
useOne("/AMY_1990_I295160/d01-x01-y02","52")
useOne("/AMY_1990_I295160/d01-x01-y03","55")
useOne("/AMY_1990_I295160/d01-x01-y04","56")
useOne("/AMY_1990_I295160/d01-x01-y05","57")
useOne("/AMY_1990_I295160/d01-x01-y06","60")
useOne("/AMY_1990_I295160/d01-x01-y07","60.8")
useOne("/AMY_1990_I295160/d01-x01-y08","61.4")
useOne("/AMY_1990_I295160/d01-x01-y09","57")
useOne("/AMY_1990_I295160/d02-x02-y01","57")
merge("/AMY_1990_I295160/d02-x01-y01")
merge("/JADE_1983_I190818/d01-x01-y01")
merge("/PLUTO_1980_I154270/d01-x01-y01")
merge("/TASSO_1989_I277658/d02-x01-y01")
useOne("/TASSO_1989_I277658/d05-x01-y01","14")
useOne("/TASSO_1989_I277658/d05-x01-y02","22")
useOne("/TASSO_1989_I277658/d05-x01-y03","34.8")
useOne("/TASSO_1989_I277658/d05-x01-y04","43.6")
# BELLE
useOne("/BELLE_2006_S6265367/d01-x01-y01","10.52")
useOne("/BELLE_2006_S6265367/d01-x01-y02","10.52")
useOne("/BELLE_2006_S6265367/d01-x01-y03","10.52")
useOne("/BELLE_2006_S6265367/d01-x01-y04","10.52")
useOne("/BELLE_2006_S6265367/d01-x01-y05","10.52")
useOne("/BELLE_2006_S6265367/d01-x01-y06","10.52")
useOne("/BELLE_2006_S6265367/d01-x01-y07","10.52")
useOne("/BELLE_2006_S6265367/d01-x01-y08","10.52")
useOne("/BELLE_2006_S6265367/d02-x01-y01","10.52")
useOne("/BELLE_2006_S6265367/d02-x01-y02","10.52")
useOne("/BELLE_2006_S6265367/d03-x01-y01","10.52")
useOne("/BELLE_2006_S6265367/d03-x01-y02","10.52")
useOne("/BELLE_2006_S6265367/d04-x01-y01","10.52")
useOne("/BELLE_2006_S6265367/d04-x01-y02","10.52")
useOne("/BELLE_2006_S6265367/d05-x01-y01","10.52")
useOne("/BELLE_2006_S6265367/d05-x01-y02","10.52")
useOne("/BELLE_2006_S6265367/d06-x01-y01","10.52")
useOne("/BELLE_2006_S6265367/d06-x01-y02","10.52")
useOne("/BELLE_2006_S6265367/d07-x01-y01","10.52")
useOne("/BELLE_2006_S6265367/d07-x01-y02","10.52")
useOne("/BELLE_2006_S6265367/d08-x01-y01","10.52")
useOne("/BELLE_2006_S6265367/d08-x01-y02","10.52")
useOne("/BELLE_2006_S6265367/d09-x01-y01","U4")
useOne("/BELLE_2006_S6265367/d09-x01-y02","U4")
useOne("/BELLE_2006_S6265367/d10-x01-y01","U4")
useOne("/BELLE_2006_S6265367/d10-x01-y02","U4")
useOne("/BELLE_2006_S6265367/d11-x01-y01","U4")
useOne("/BELLE_2006_S6265367/d11-x01-y02","U4")
useOne("/BELLE_2006_S6265367/d12-x01-y01","U4")
useOne("/BELLE_2006_S6265367/d12-x01-y02","U4")
useOne("/BELLE_2006_S6265367/d13-x01-y01","U4")
useOne("/BELLE_2006_S6265367/d13-x01-y02","U4")
useOne("/BELLE_2006_S6265367/d14-x01-y01","U4")
useOne("/BELLE_2006_S6265367/d14-x01-y02","U4")
useOne("/BELLE_2006_S6265367/d15-x01-y01","U4")
useOne("/BELLE_2006_S6265367/d15-x01-y02","U4")
# BABAR
useOne("/BABAR_2007_S6895344/d01-x01-y01","10.54")
useOne("/BABAR_2007_S6895344/d02-x01-y01","10.54")
useOne("/BABAR_2007_S6895344/d03-x01-y01","U4")
useOne("/BABAR_2007_S6895344/d04-x01-y01","U4")
# BABAR
useOne("/BABAR_2005_S6181155/d01-x01-y01","10.58")
useOne("/BABAR_2005_S6181155/d02-x01-y01","10.58")
useOne("/BABAR_2005_S6181155/d02-x01-y02","10.54")
useOne("/BABAR_2005_S6181155/d03-x01-y01","10.54")
useOne("/BABAR_2005_S6181155/d04-x01-y01","10.58")
useOne("/BABAR_2005_S6181155/d05-x01-y01","10.58")
useOne("/BABAR_2005_S6181155/d05-x01-y02","10.54")
# ARGUS
useOne("/ARGUS_1993_S2789213/d01-x01-y01","10.45")
useOne("/ARGUS_1993_S2789213/d01-x01-y02","10.45")
useOne("/ARGUS_1993_S2789213/d01-x01-y03","10.45")
useOne("/ARGUS_1993_S2789213/d01-x01-y04","10.45")
useOne("/ARGUS_1993_S2789213/d01-x01-y05","10.45")
useOne("/ARGUS_1993_S2789213/d02-x01-y01", "U1")
useOne("/ARGUS_1993_S2789213/d02-x01-y02", "U1")
useOne("/ARGUS_1993_S2789213/d02-x01-y03", "U1")
useOne("/ARGUS_1993_S2789213/d02-x01-y04", "U1")
useOne("/ARGUS_1993_S2789213/d02-x01-y05", "U1")
useOne("/ARGUS_1993_S2789213/d03-x01-y01","U4")
useOne("/ARGUS_1993_S2789213/d03-x01-y02","U4")
useOne("/ARGUS_1993_S2789213/d03-x01-y03","U4")
useOne("/ARGUS_1993_S2789213/d03-x01-y04","U4")
useOne("/ARGUS_1993_S2789213/d03-x01-y05","U4")
useOne("/ARGUS_1993_S2789213/d04-x01-y01","10.45")
useOne("/ARGUS_1993_S2789213/d05-x01-y01", "U1")
useOne("/ARGUS_1993_S2789213/d06-x01-y01","U4")
useOne("/ARGUS_1993_S2789213/d07-x01-y01","10.45")
useOne("/ARGUS_1993_S2789213/d08-x01-y01", "U1")
useOne("/ARGUS_1993_S2789213/d09-x01-y01","U4")
useOne("/ARGUS_1993_S2789213/d10-x01-y01","10.45")
useOne("/ARGUS_1993_S2789213/d11-x01-y01", "U1")
useOne("/ARGUS_1993_S2789213/d12-x01-y01","U4")
useOne("/ARGUS_1993_S2789213/d13-x01-y01","10.45")
useOne("/ARGUS_1993_S2789213/d14-x01-y01", "U1")
useOne("/ARGUS_1993_S2789213/d15-x01-y01","U4")
if("/ARGUS_1993_S2669951/d04-x01-y01" in outhistos) :
useOne("/ARGUS_1993_S2669951/d02-x01-y01","10.45")
useOne("/ARGUS_1993_S2669951/d03-x01-y01","U1")
useOne("/ARGUS_1993_S2669951/d04-x01-y01","U2")
merge("/ARGUS_1993_S2669951/d01-x01-y01")
merge("/ARGUS_1993_S2669951/d01-x01-y02")
merge("/ARGUS_1993_S2669951/d05-x01-y01")
useOne("/ARGUS_1990_I278933/d01-x01-y01","9.46")
useOne("/ARGUS_1990_I278933/d01-x01-y02","U1")
useOne("/ARGUS_1990_I278933/d01-x01-y03","U2")
useOne("/ARGUS_1990_I278933/d02-x01-y01","9.46")
useOne("/ARGUS_1990_I278933/d02-x01-y02","U1")
useOne("/ARGUS_1990_I278933/d02-x01-y03","U2")
useOne("/ARGUS_1990_I278933/d03-x01-y01","9.46")
useOne("/ARGUS_1990_I278933/d03-x01-y02","9.46")
useOne("/ARGUS_1990_I278933/d04-x01-y01","U1")
useOne("/ARGUS_1990_I278933/d04-x01-y02","U2")
useOne("/ARGUS_1990_I278933/d05-x01-y01","9.46")
useOne("/ARGUS_1990_I278933/d05-x01-y02","9.46")
useOne("/ARGUS_1990_I278933/d06-x01-y01","U1")
useOne("/ARGUS_1990_I278933/d06-x01-y02","U2")
+useOne("/CRYSTAL_BALL_1991_I297905/d01-x01-y01","9.46")
+useOne("/CRYSTAL_BALL_1991_I297905/d01-x01-y02","9.46")
+useOne("/CRYSTAL_BALL_1991_I297905/d02-x01-y01","U1")
+useOne("/CRYSTAL_BALL_1991_I297905/d02-x01-y02","U1")
+useOne("/CRYSTAL_BALL_1991_I297905/d03-x01-y01","9.46")
+useOne("/CRYSTAL_BALL_1991_I297905/d03-x01-y02","9.46")
+useOne("/CRYSTAL_BALL_1991_I297905/d04-x01-y01","U1")
+useOne("/CRYSTAL_BALL_1991_I297905/d05-x01-y01","9.46")
+useOne("/CRYSTAL_BALL_1991_I297905/d05-x01-y02","9.46")
+useOne("/CRYSTAL_BALL_1991_I297905/d06-x01-y01","U1")
+
useOne("/ARGUS_1989_I262551/d01-x01-y01","10.00")
useOne("/ARGUS_1989_I262551/d02-x01-y01","U1")
useOne("/ARGUS_1989_I262551/d02-x01-y02","U2")
useOne("/ARGUS_1989_I262551/d03-x01-y01","U1")
useOne("/ARGUS_1989_I262551/d04-x01-y01","U2")
merge("/ARGUS_1989_I276860/d01-x01-y01")
merge("/ARGUS_1989_I276860/d01-x01-y02")
merge("/ARGUS_1989_I276860/d02-x01-y01")
merge("/ARGUS_1989_I276860/d03-x01-y01")
merge("/ARGUS_1989_I276860/d04-x01-y01")
merge("/ARGUS_1989_I276860/d04-x01-y02")
for i in range(5,13) :
useOne("/ARGUS_1989_I276860/d%02d-x01-y01" %i,"U1")
useOne("/ARGUS_1989_I276860/d%02d-x01-y02" %i,"10.00")
for i in range(1,8) :
useOne("/ARGUS_1988_I251097/d01-x01-y%02d" %i,"U1")
useOne("/ARGUS_1988_I251097/d02-x01-y%02d" %i,"10.00")
useOne("/ARGUS_1988_I251097/d03-x01-y01","U1")
useOne("/ARGUS_1988_I251097/d04-x01-y01","U2")
useOne("/ARGUS_1988_I251097/d05-x01-y01","10.00")
useOne("/ARGUS_1988_I251097/d06-x01-y01","10.00")
useOne("/ARGUS_1988_I251097/d07-x01-y01","U1")
useOne("/ARGUS_1988_I251097/d08-x01-y01","U2")
useOne("/ARGUS_1988_I251097/d09-x01-y01","10.00")
useOne("/ARGUS_1989_I262415/d03-x01-y01","U1")
useOne("/ARGUS_1989_I262415/d04-x01-y01","10.00")
useOne("/ARGUS_1989_I262415/d01-x01-y01","U1")
useOne("/ARGUS_1989_I262415/d01-x01-y02","10.00")
useOne("/ARGUS_1989_I262415/d01-x02-y01","U1")
useOne("/ARGUS_1989_I262415/d01-x02-y02","10.00")
merge("/PLUTO_1981_I165122/d02-x01-y01")
useOne("/PLUTO_1981_I165122/d06-x01-y01","U1")
useOne("/PLUTO_1981_I165122/d04-x01-y01","30.2")
useOne("/PLUTO_1981_I165122/d05-x01-y01","9.4")
useOne("/PLUTO_1977_I118873/d02-x01-y01","3.63")
useOne("/PLUTO_1977_I118873/d03-x01-y01","4.03")
useOne("/PLUTO_1977_I118873/d04-x01-y01","4.5")
useOne("/TASSO_1982_I177174/d01-x01-y01","14.")
useOne("/TASSO_1982_I177174/d01-x01-y02","22.")
useOne("/TASSO_1982_I177174/d01-x01-y03","34.")
for i in range(2,4) :
useOne("/TASSO_1982_I177174/d0%s-x01-y01" %i ,"12.")
useOne("/TASSO_1982_I177174/d0%s-x01-y02" %i ,"14.")
useOne("/TASSO_1982_I177174/d0%s-x01-y03" %i ,"22.")
useOne("/TASSO_1982_I177174/d0%s-x01-y04" %i ,"25.")
useOne("/TASSO_1982_I177174/d0%s-x01-y05" %i ,"30.")
useOne("/TASSO_1982_I177174/d0%s-x01-y06" %i ,"34.")
useOne("/TASSO_1982_I177174/d0%s-x01-y07" %i ,"35.")
merge("/TASSO_1980_I143691/d01-x01-y01")
useOne("/TASSO_1980_I143691/d02-x01-y01","13.")
useOne("/TASSO_1980_I143691/d05-x01-y01","13.")
-if("/TASSO_1980_I143691/d03-x01-y01" in inhistos and
- "17." in inhistos["/TASSO_1980_I143691/d03-x01-y01"] and
- "22." in inhistos["/TASSO_1980_I143691/d03-x01-y01"]) :
- average("/TASSO_1980_I143691/d03-x01-y01","17.","22.")
- average("/TASSO_1980_I143691/d06-x01-y01","17.","22.")
-useOne("/TASSO_1980_I143691/d04-x01-y01","30.2")
-useOne("/TASSO_1980_I143691/d07-x01-y01","30.2")
+for ih in [3,6] :
+ if(("/TASSO_1980_I143691/d0%s-x01-y01"%ih) in inhistos and
+ 17. in inhistos["/TASSO_1980_I143691/d0%s-x01-y01"%ih] and
+ 22. in inhistos["/TASSO_1980_I143691/d0%s-x01-y01"%ih]) :
+ average("/TASSO_1980_I143691/d0%s-x01-y01"%ih,"17.","22.")
+useOne("/TASSO_1980_I143691/d04-x01-y01","30.3")
+useOne("/TASSO_1980_I143691/d07-x01-y01","30.3")
useOne("/TASSO_1990_I284251/d01-x01-y01","42.6")
useOne("/TASSO_1990_I284251/d01-x01-y02","35.")
useOne("/TASSO_1990_I284251/d01-x01-y03","34.5")
useOne("/TASSO_1990_I284251/d02-x01-y01","14.8")
useOne("/TASSO_1990_I284251/d03-x01-y01","21.5")
merge("/TASSO_1990_I284251/d04-x01-y01")
useOne("/TASSO_1990_I284251/d05-x01-y01","42.6")
useOne("/TASSO_1990_I284251/d05-x01-y02","42.6")
useOne("/TASSO_1990_I284251/d05-x01-y03","35")
useOne("/TASSO_1990_I284251/d05-x01-y04","35")
useOne("/TASSO_1990_I284251/d06-x01-y01","14.8")
useOne("/TASSO_1990_I284251/d06-x01-y02","14.8")
useOne("/TASSO_1990_I284251/d07-x01-y01","21.5")
useOne("/TASSO_1990_I284251/d07-x01-y02","21.5")
useOne("/TASSO_1990_I284251/d08-x01-y01","42.6")
useOne("/TASSO_1990_I284251/d08-x01-y02","35.")
useOne("/TASSO_1990_I284251/d08-x01-y03","34.5")
merge("/TASSO_1990_I284251/d09-x01-y01")
useOne("/TASSO_1990_I284251/d10-x01-y01","35")
useOne("/TASSO_1990_I284251/d10-x01-y02","35")
merge("/DASP_1979_I132410/d01-x01-y01")
# BES xi analysis
useOne("/BESIII_2016_I1422780/d02-x01-y01","psi")
useOne("/BESIII_2016_I1422780/d02-x01-y02","psi")
useOne("/BESIII_2016_I1422780/d02-x01-y03","psi")
useOne("/BESIII_2016_I1422780/d02-x01-y04","psi2s")
useOne("/BESIII_2016_I1422780/d02-x01-y05","psi2s")
useOne("/BESIII_2016_I1422780/d02-x01-y06","psi2s")
if ( "/BESIII_2016_I1422780/d01-x01-y03" in inhistos and
"psi" in inhistos["/BESIII_2016_I1422780/d01-x01-y03"]) :
for point in inhistos["/BESIII_2016_I1422780/d01-x01-y03"]["psi"].points():
outhistos["/BESIII_2016_I1422780/d01-x01-y03"].addPoint(point)
if ( "/BESIII_2016_I1422780/d01-x01-y03" in inhistos and
"psi2s" in inhistos["/BESIII_2016_I1422780/d01-x01-y03"]) :
for point in inhistos["/BESIII_2016_I1422780/d01-x01-y03"]["psi2s"].points():
outhistos["/BESIII_2016_I1422780/d01-x01-y03"].addPoint(point)
# pluto analysis
for id in range(1,3) :
for iy in range(1,5) :
merge("/PLUTO_1983_I191161/d0%s-x01-y0%s" % (id,iy))
merge("/OPAL_2000_I513476/d14-x01-y01")
merge("/OPAL_2000_I513476/d20-x01-y01")
merge("/OPAL_2000_I513476/d20-x01-y02")
merge("/OPAL_2000_I513476/d20-x01-y03")
merge("/OPAL_2000_I513476/d20-x01-y04")
merge("/JADE_1979_I142874/d02-x01-y01")
merge("/LENA_1981_I164397/d03-x01-y01")
useOne("/LENA_1981_I164397/d04-x01-y01","9.51")
useOne("/LENA_1981_I164397/d04-x01-y02","10.")
useOne("/LENA_1981_I164397/d04-x01-y03","U1")
useOne("/LENA_1981_I164397/d04-x01-y04","U2")
useOne("/ARGUS_1991_I315059/d01-x01-y01","10.47")
useOne("/ARGUS_1991_I315059/d01-x01-y02","10.47")
useOne("/ARGUS_1991_I315059/d01-x01-y03","10.47")
useOne("/ARGUS_1991_I315059/d02-x01-y01","10.47")
useOne("/ARGUS_1991_I315059/d03-x01-y01","10.47")
useOne("/ARGUS_1991_I315059/d04-x01-y01","10.47")
useOne("/ARGUS_1991_I315059/d05-x01-y01","U4")
useOne("/ARGUS_1991_I315059/d06-x01-y01","U4")
useOne("/ARGUS_1991_I315059/d07-x01-y01","U4")
for i in [3,4,5,6,7,8,18,19,20,21,22,23] :
useOne("/TASSO_1989_I266893/d%02d-x01-y01" %i ,"34.8")
for i in range(9,15) :
useOne("/TASSO_1989_I266893/d%02d-x01-y01" %i ,"42.1")
for i in range(1,4) :
useOne("/TASSO_1989_I266893/d15-x01-y%02d" %i ,"34.8")
useOne("/TASSO_1989_I266893/d16-x01-y%02d" %i ,"42.1")
for i in range(1,12) :
useOne("/CLEO_1985_I205668/d%02d-x01-y01" %i ,10.47)
useOne("/CLEO_1985_I205668/d%02d-x01-y02" %i , "U1")
for i in range(12,24) :
merge("/CLEO_1985_I205668/d%02d-x01-y01" %i)
useOne("/BABAR_2014_I1286317/d01-x01-y01", "U3")
useOne("/BABAR_2014_I1286317/d02-x01-y01", "U2")
useOne("/BABAR_2014_I1286317/d03-x01-y01", "U1")
useOne("/BABAR_2014_I1286317/d06-x01-y01", "U3")
useOne("/BABAR_2014_I1286317/d06-x02-y01", "U2")
useOne("/BABAR_2014_I1286317/d06-x03-y01", "U1")
useOne("/BABAR_2014_I1286317/d04-x01-y01", "10.6")
useOne("/BABAR_2014_I1286317/d05-x01-y01", "10.6")
useOne("/BABAR_2014_I1286317/d06-x04-y01", "10.6")
-
-
+
+for ix in range(0,2) :
+ if ix==0 : en="189"
+ else : en="183"
+ for iy in range(1,3) :
+ useOne("/DELPHI_2001_I526164/d%02d-x01-y0%s"%(5+2*ix,iy), en)
+ useOne("/DELPHI_2001_I526164/d%02d-x01-y01"%(6+2*ix), en)
+ for iloc in range(2,5,2) :
+ useOne("/DELPHI_2001_I526164/d16-x01-y%02d"%(iloc-ix), en)
+ for iy in range(1,5) :
+ useOne("/DELPHI_2001_I526164/d%02d-x01-y0%s"%(9 +ix,iy), en)
+ useOne("/DELPHI_2001_I526164/d%02d-x01-y0%s"%(11+ix,iy), en)
+for ix in range(13,16) :
+ for iy in range(1,5) :
+ useOne("/DELPHI_2001_I526164/d%02d-x01-y0%s"%(ix,iy), "189")
+merge("/DELPHI_2001_I526164/d01-x01-y01")
+for ix in range(1,6) :
+ merge("/DELPHI_2001_I526164/d02-x01-y0%s"%ix)
+for ix in range(1,7) :
+ useOne("/DELPHI_2001_I526164/d04-x01-y0%s"%ix,"189")
+# weird histo, select bins by hand
+if "/DELPHI_2001_I526164/d03-x01-y01" in inhistos:
+ outhistos["/DELPHI_2001_I526164/d03-x01-y01"].addPoint(inhistos["/DELPHI_2001_I526164/d03-x01-y01"][183.].points()[0])
+ outhistos["/DELPHI_2001_I526164/d03-x01-y01"].addPoint(inhistos["/DELPHI_2001_I526164/d03-x01-y01"][189.].points()[1])
+ outhistos["/DELPHI_2001_I526164/d03-x01-y01"].addPoint(inhistos["/DELPHI_2001_I526164/d03-x01-y01"][183.].points()[2])
+ outhistos["/DELPHI_2001_I526164/d03-x01-y01"].addPoint(inhistos["/DELPHI_2001_I526164/d03-x01-y01"][189.].points()[3])
+
+useOne("/MARKII_1982_I178416/d01-x01-y01","5.2")
+useOne("/MARKII_1982_I178416/d01-x01-y02","6.5")
+useOne("/MARKII_1982_I178416/d01-x01-y03","29.0")
+
+for ih in [3,5,6,7,8,9,10,11,12,13,14] :
+ eTemp=["14","22","34"]
+ for iy in range(0,3) :
+ useOne("/TASSO_1984_I195333/d%02d-x01-y%02d" %(ih,iy+1) , eTemp[iy])
+for iy in range(1,12) :
+ merge("/TASSO_1984_I195333/d04-x01-y%02d"%iy)
# normalize where we have sum histos
for i in range(1,5) :
hname="/BABAR_2007_I746745/d0%s-x01-y01" %i
if(hname in outhistos and outhistos[hname].effNumEntries()!=0.) :
outhistos[hname].normalize()
# Choose output file
name = args[0]+".yoda"
+removeNan()
# output the yoda file
yoda.writeYODA(outhistos,name)
sys.exit(0)
diff --git a/Tests/python/merge-GammaGamma.in b/Tests/python/merge-GammaGamma.in
--- a/Tests/python/merge-GammaGamma.in
+++ b/Tests/python/merge-GammaGamma.in
@@ -1,125 +1,126 @@
#! @PYTHON@
+# -*- mode: python -*-
from __future__ import print_function
import logging,sys
import os, yoda, copy
if sys.version_info[:3] < (2,4,0):
print ("rivet scripts require Python version >= 2.4.0... exiting")
sys.exit(1)
#############################################
def fillAbove(desthisto, sourcehistosbysqrts):
if type(desthisto) is yoda.core.Scatter2D :
for sqrts in sorted(sourcehistosbysqrts.keys()) :
h=sourcehistosbysqrts[sqrts]
- for i in range(0,h.numPoints) :
- if sqrts==h.points[i].x :
- desthisto.addPoint(h.points[i])
+ for i in range(0,h.numPoints()) :
+ if sqrts==h.points()[i].x() :
+ desthisto.addPoint(h.points()[i])
elif(type(desthisto)==yoda.core.Profile1D) :
for sqrts, h in sorted(sourcehistosbysqrts.items()) :
- for i in range(0,h.numBins) :
- if(sqrts>=h.bins[i].xMin and \
- sqrts<=h.bins[i].xMax) :
- desthisto.bins[i] += h.bins[i]
+ for i in range(0,h.numBins()) :
+ if(sqrts>=h.bins()[i].xMin() and \
+ sqrts<=h.bins()[i].xMax()) :
+ desthisto.bins[i] += h.bins()[i]
break
else :
logging.error("Unknown analysis object" + desthisto.path)
sys.exit(1)
def merge(hpath):
global inhistos
global outhistos
try:
fillAbove(outhistos[hpath], inhistos[hpath])
except:
pass
def useOne(hpath, sqrts):
global inhistos
global outhistos
try:
outhistos[hpath] = inhistos[hpath][float(sqrts)]
except:
pass
if __name__ == "__main__":
import logging
from optparse import OptionParser, OptionGroup
parser = OptionParser(usage="%prog name")
verbgroup = OptionGroup(parser, "Verbosity control")
verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL",
default=logging.INFO, help="print debug (very verbose) messages")
verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL",
default=logging.INFO, help="be very quiet")
parser.add_option_group(verbgroup)
(opts, args) = parser.parse_args()
logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s")
## Check args
if len(args) < 1:
logging.error("Must specify at least the name of the files")
sys.exit(1)
#######################################
yodafiles=["-mumu-3.5","-mumu-4.5","-mumu-5.5","-mumu-6.5","-mumu-7.5","-mumu-9.0","-mumu-12.5","-mumu-17.5","-mumu-30.0"]
# Get histos
inhistos = {}
outhistos = {}
for f in yodafiles:
file = "Rivet-%s%s.yoda" % (args[0], f)
sqrts=float(f.split("-")[-1].replace(".yoda",""))
if not os.access(file, os.R_OK):
logging.error("%s cannot be read" % file)
continue
try:
aos = yoda.read(file)
except:
logging.error("%s cannot be parsed as yoda" % file)
continue
## Get histos from this YODA file
for aopath, ao in aos.items() :
if("RAW" in aopath or "_XSEC" in aopath or "_EVTCOUNT" in aopath ) :continue
# merge of different energy values
if("L3_2004_I645127" in aopath) :
if aopath not in inhistos:
inhistos[aopath] = {}
if sqrts not in inhistos[aopath]:
inhistos[aopath][sqrts] = ao
else:
raise Exception("A set with sqrts = %s already exists" % ( sqrts))
else :
outhistos[aopath] = ao
## Make empty output histos if needed
for hpath,hsets in inhistos.items():
if("L3_2004_I645127" in hpath ) :
hist = list(hsets.values())[0]
if(type(hist)==yoda.core.Scatter2D) :
outhistos[hpath] = yoda.core.Scatter2D(hist.path(),
hist.title())
elif(type(hist)==yoda.core.Profile1D) :
outhistos[hpath] = yoda.core.Profile1D(hist.path(),
hist.title())
for i in range(0,hist.numBins) :
outhistos[hpath].addBin(hist.bins()[i].xMin(),
hist.bins()[i].xMax())
elif(type(hist)==yoda.core.Histo1D) :
outhistos[hpath] = yoda.core.Histo1D(hist.path(),
hist.title())
for i in range(0,hist.numBins) :
outhistos[hpath].addBin(hist.bins()[i].xMin(),
hist.bins()[i].xMax())
else :
logging.error("Histogram %s is of unknown type" % hpath)
sys.exit(1)
merge("/L3_2004_I645127:PROCESS=GG/d03-x01-y05")
# Choose output file
name = args[0]+".yoda"
# output the yoda file
print ("Write yoda to ",name)
yoda.writeYODA(outhistos,name)
sys.exit(0)
diff --git a/Tests/python/merge-LHC-Jets.in b/Tests/python/merge-LHC-Jets.in
--- a/Tests/python/merge-LHC-Jets.in
+++ b/Tests/python/merge-LHC-Jets.in
@@ -1,1749 +1,1749 @@
#! @PYTHON@
from __future__ import print_function
import logging, sys, math
if sys.version_info[:3] < (2,4,0):
print ("rivet scripts require Python version >= 2.4.0... exiting")
sys.exit(1)
import os, yoda
# #############################################
def rescale(path,scale) :
if(path not in outhistos) : return
outhistos[path].scaleW(scale)
def fillAbove(scale,desthisto, sourcehistosbyptmin) :
pthigh= 1e100
ptlow =-1e100
for pt, h in sorted(sourcehistosbyptmin.items(),reverse=True):
ptlow=pt
if(type(desthisto)==yoda.core.Scatter2D) :
for i in range(0,h.numPoints()) :
xMin = h.points()[i].x()-h.points()[i].xErrs().minus
if( xMin*scale >= ptlow and
xMin*scale < pthigh ) :
desthisto.addPoint(h.points()[i])
elif(type(desthisto)==yoda.core.Profile1D) :
for i in range(0,h.numBins()) :
if(h.bins()[i].xMin()*scale >= ptlow and
h.bins()[i].xMin()*scale < pthigh ) :
desthisto.bins()[i] += h.bins()[i]
elif(type(desthisto)==yoda.core.Histo1D) :
for i in range(0,h.numBins()) :
if(h.bins()[i].xMin()*scale >= ptlow and
h.bins()[i].xMin()*scale < pthigh ) :
desthisto.bins()[i] += h.bins()[i]
elif(type(desthisto)==yoda.core.Counter) :
desthisto += h
else :
logging.error("Can't merge %s, unknown type" % desthisto.path())
sys.exit(1)
pthigh=pt
def mergeByPt(hpath, sqrts, scale=1.) :
global inhistos_pt
global outhistos
try:
fillAbove(scale,outhistos[hpath], inhistos_pt[hpath][float(sqrts)])
except:
pass
def mergeByMass(hpath, sqrts, scale=1.):
global inhistos_mass
global outhistos
try:
fillAbove(scale,outhistos[hpath], inhistos_mass[hpath][float(sqrts)])
except:
pass
def useOnePt(hpath, sqrts, ptmin):
global inhistos_pt
global outhistos
try:
## Find best pT_min match
ptmins = inhistos_pt[hpath][float(sqrts)].keys()
closest_ptmin = None
for ptm in ptmins:
if closest_ptmin is None or \
abs(ptm-float(ptmin)) < abs(closest_ptmin-float(ptmin)):
closest_ptmin = ptm
if closest_ptmin != float(ptmin):
logging.warning("Inexact match for requested pTmin=%s: " % ptmin + \
"using pTmin=%e instead" % closest_ptmin)
outhistos[hpath] = inhistos_pt[hpath][float(sqrts)][closest_ptmin]
except:
pass
def useOneMass(hpath, sqrts, ptmin):
global inhistos_pt
global outhistos
try:
## Find best pT_min match
ptmins = inhistos_mass[hpath][float(sqrts)].keys()
closest_ptmin = None
for ptm in ptmins:
if closest_ptmin is None or \
abs(ptm-float(ptmin)) < abs(closest_ptmin-float(ptmin)):
closest_ptmin = ptm
if closest_ptmin != float(ptmin):
logging.warning("Inexact match for requested mass=%s: " % ptmin + \
"using mass=%e instead" % closest_ptmin)
outhistos[hpath] = inhistos_mass[hpath][float(sqrts)][closest_ptmin]
except:
pass
# #######################################
if __name__ == "__main__":
import logging
from optparse import OptionParser, OptionGroup
parser = OptionParser(usage="%prog name")
verbgroup = OptionGroup(parser, "Verbosity control")
parser.add_option("--with-ue",
action='store_true' ,
dest="ue",
default=True,
help="Include UE analyses")
parser.add_option("--without-ue",
action='store_false',
dest="ue",
default=True,
help="Don\'t include UE analyses")
verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL",
default=logging.INFO, help="print debug (very verbose) messages")
verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL",
default=logging.INFO, help="be very quiet")
parser.add_option_group(verbgroup)
(opts, args) = parser.parse_args()
logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s")
(opts, args) = parser.parse_args()
## Check args
if len(args) < 1:
logging.error("Must specify at least the name of the files")
sys.exit(1)
yodafiles=["-7-Bottom-0.yoda","-7-Bottom-1.yoda","-7-Bottom-2.yoda",
"-7-Bottom-3.yoda","-7-Bottom-4.yoda","-7-Bottom-5.yoda","-7-Bottom-6.yoda",
"-13-Bottom-0.yoda","-13-Bottom-1.yoda","-13-Bottom-2.yoda",
"-13-Bottom-3.yoda","-13-Bottom-4.yoda","-13-Bottom-5.yoda","-13-Bottom-6.yoda",
"-7-Charm-1.yoda","-7-Charm-2.yoda",
"-7-Charm-3.yoda","-7-Charm-4.yoda","-7-Charm-5.yoda",
"-7-Top-SL.yoda","-7-Top-L.yoda",
"-8-Top-SL.yoda","-8-Top-L.yoda","-8-Top-All.yoda",
"-13-Top-L.yoda","-13-Top-SL.yoda","-13-Top-All.yoda"]
for i in range(1,11) :
for j in [7,8,13] :
yodafiles.append("-%1.1i-Jets-%1.1i.yoda" % (j,i))
for i in range(1,4) :
yodafiles.append("-2760-Jets-%1.1i.yoda" % i)
if(opts.ue) :
yodafiles += ["-7-Jets-0.yoda" ,"-8-Jets-0.yoda" ,
"-900-UE.yoda" ,"-2360-UE.yoda" ,
"-2760-UE.yoda" ,"-7-UE.yoda" ,
"-900-UE-Long.yoda" ,"-8-UE.yoda" ,
- "-7-UE-Long.yoda","-13-UE.yoda","-13-UE-Long.yoda",
- "-7-UE-Cent.yoda","-13-UE-Cent.yoda"]
+ "-7-UE-Long.yoda","-13-UE.yoda","-13-UE-Long.yoda"]
+# "-7-UE-Cent.yoda","-13-UE-Cent.yoda"]
## Get histos
inhistos_pt = {}
inhistos_mass = {}
outhistos={}
weights = {}
for f in yodafiles:
file='Rivet-'+args[0]+f
ptmin=0.
sqrts=7000
# CMS energy
if(file.find("-900-")>0) :
sqrts=900
elif(file.find("-2360-")>0) :
sqrts=2360
elif(file.find("-2760-")>0) :
sqrts=2760
elif(file.find("-7-")>=0) :
sqrts=7000
elif(file.find("-8-")>=0) :
sqrts=8000
elif(file.find("-13-")>0) :
sqrts=13000
# pT min
if(file.find("UE")>0) :
ptmin=0.
elif(file.find("Jets-0")>0) :
ptmin=4.
elif(file.find("Jets-10")>0) :
ptmin=1900.
elif(file.find("Jets-1")>0) :
if( not opts.ue) :
ptmin = 10.
else :
ptmin = 20.
elif(file.find("Jets-2")>0) :
ptmin=40.
elif(file.find("Jets-3")>0) :
ptmin=80.
elif(file.find("Jets-4")>0) :
ptmin=110.
elif(file.find("Jets-5")>0) :
ptmin=210.
elif(file.find("Jets-6")>0) :
ptmin=260.
elif(file.find("Jets-7")>0) :
ptmin=400.
elif(file.find("Jets-8")>0) :
ptmin=600.
elif(file.find("Jets-9")>0) :
ptmin=900.
elif(file.find("Bottom-0")>0) :
ptmin=0.
elif(file.find("Bottom-1")>0 or file.find("Charm-1")>0) :
ptmin=10.
elif(file.find("Bottom-2")>0 or file.find("Charm-2")>0) :
ptmin=20.
elif(file.find("Bottom-3")>0 or file.find("Charm-3")>0) :
ptmin=30.
elif(file.find("Bottom-4")>0 or file.find("Charm-4")>0) :
ptmin=70.
elif(file.find("Bottom-5")>0 or file.find("Charm-5")>0) :
ptmin=100.
elif(file.find("Bottom-6")>0 or file.find("Charm-6")>0) :
ptmin=130.
elif(file.find("Top-SL.yoda")>0 or file.find("Top-L.yoda")>0 or \
file.find("Top-All.yoda")>0):
ptmin=0.
if not os.access(file, os.R_OK):
logging.error("%s can not be read" % file)
continue
try:
aos = yoda.read(file)
except:
logging.error("%s can not be parsed as YODA" % file)
continue
## Get histos from this YODA file
for aopath, ao in aos.items() :
if "RAW" in aopath : continue
if("S8924791" in aopath or "S8971293" in aopath or
"S8817804" in aopath or "I1082936" in aopath or
"S8994773" in aopath or "S8918562" in aopath or
"S8624100" in aopath or "S8625980" in aopath or
"S8894728" in aopath or "S8957746" in aopath or
"S9126244" in aopath or "S9120041" in aopath or
"S8950903" in aopath or "S9086218" in aopath or
"S9088458" in aopath or "I919017" in aopath or
"I926145" in aopath or "S8941262" in aopath or
"S8973270" in aopath or "I1118269" in aopath or
"I1188891" in aopath or "I1082009" in aopath or
"I1087342" in aopath or "S9035664" in aopath or
"I1125575" in aopath or "I1094564" in aopath or
"I930220" in aopath or "I1224539" in aopath or
"I1273574" in aopath or "I1261026" in aopath or
"I1307243" in aopath or "I1325553" in aopath or
"I1298810" in aopath or "I1298811" in aopath or
"I1208923" in aopath or "I1305624" in aopath or
"I1419070" in aopath or "I1394679" in aopath or
"I929691" in aopath or "I1393758" in aopath or
"I1459051" in aopath or "I1487277" in aopath or
"I1421646" in aopath or "I1111014" in aopath or
"I1605749" in aopath or "I1682495" in aopath or
"I1609253" in aopath or "1385107" in aopath or
"I1486238" in aopath or "1634970" in aopath or
"I1604271" in aopath or "I1598460" in aopath or
"I1643640" in aopath or "I1808726" in aopath or
"I1724098" in aopath or "I1719955" in aopath or
"I1740909" in aopath or "I1913061" in aopath or
"ATLAS_2016_CONF_2016_092" in aopath or
"CMS_2012_PAS_QCD_11_010" in aopath) :
if("1419070" in aopath and ("forward" in aopath or "central" in aopath )) :
continue
if aopath not in inhistos_pt:
inhistos_pt[aopath] = {}
tmpE = inhistos_pt[aopath]
if sqrts not in tmpE:
tmpE[sqrts] = {}
if ptmin not in tmpE[sqrts]:
tmpE[sqrts][ptmin] = ao
else:
tmpE[sqrts][ptmin] += ao
#raise Exception("A set with ptmin = %s already exists" % ( ptmin))
else :
if("1509919" in aopath and "Ctr_cut" in aopath) :
continue
elif "I1393758" in aopath and ("d02" in aopath or "d04" in aopath or
"d06" in aopath or "d08" in aopath or
"d10" in aopath or "d12" in aopath) :
continue
elif "1387176" in aopath and "y02" in aopath:
continue
elif "1454211" in aopath and "cutflow" in aopath :
continue
elif("ATLAS_2016_I1468168" in aopath) :
newPath=aopath.replace("Passed_events","d02-x01-y01")
outhistos[newPath] = ao
ao.setPath(newPath)
elif(aopath.find("I1243871")>0) :
if(aopath.find("x01")>0 and file.find("-7-Top-L.yoda")>0 ) :
outhistos[aopath] = ao
elif(aopath.find("x02")>0 and file.find("-7-Top-SL.yoda")>0 ) :
outhistos[aopath] = ao
elif(aopath.find("1467230")>0 or aopath.find("1419652")>0) :
if(aopath.find("y01")>0 and file.find("Long")>0 ) :
outhistos[aopath] = ao
elif(aopath.find("y02")>0 and file.find("Long")<0 ) :
outhistos[aopath] = ao
elif("CMS_2017_I1471287" in aopath) :
if("CMS_2017_I1471287/d" in aopath) :
outhistos[aopath] = ao
elif("ATLAS_2018_I1705857" in aopath ) :
ihist = int(aopath.split("/d")[1].split("-")[0])
if "-SL" in file :
if ihist in [9,10,11,12,19,20,21,22,23,24,25,26,33,34,35,36,37,38,45,46,47,48,49,50] :
outhistos[aopath] = ao
elif "-L" in file :
if ihist in [3,4,5,6,7,8,13,14,15,16,17,18,27,28,29,30,31,32,39,40,41,42,43,44] :
outhistos[aopath] = ao
if ihist in [1,2] :
if aopath not in outhistos :
outhistos[aopath] = ao
else :
title=""
path=""
if hasattr(ao, 'title'):
title=ao.title()
if hasattr(ao, 'path'):
path=ao.path()
temp = yoda.core.Histo1D(path,title)
for i in range(0,ao.numBins()) :
temp.addBin(ao.bins()[i].xMin(),ao.bins()[i].xMax())
if("-SL" in file) :
temp.bins()[0] += outhistos[aopath].bins()[0]
temp.bins()[1] += outhistos[aopath].bins()[1]
temp.bins()[2] += ao.bins()[2]
temp.bins()[3] += ao.bins()[3]
temp.bins()[2] += ao.bins()[2]
temp.bins()[3] += ao.bins()[3]
else :
temp.bins()[0] += ao.bins()[0]
temp.bins()[1] += ao.bins()[1]
temp.bins()[2] += outhistos[aopath].bins()[2]
temp.bins()[3] += outhistos[aopath].bins()[3]
temp.bins()[2] += outhistos[aopath].bins()[2]
temp.bins()[3] += outhistos[aopath].bins()[3]
outhistos[aopath] = temp
elif "ATLAS_2018_I1707015" in aopath :
if "d03" in aopath or "d04" in aopath or "d05" in aopath:
if "Top-SL" in file:
outhistos[aopath] = ao
else :
if( "Top-L" in file ) :
outhistos[aopath] = ao
else :
outhistos[aopath] = ao
yodafiles=["-7-Bottom-7.yoda","-7-Bottom-8.yoda","-7-Bottom-9.yoda"]
for i in range(1,8) :
yodafiles.append("-7-DiJets-%1.1i-A.yoda" % i)
yodafiles.append("-7-DiJets-%1.1i-B.yoda" % i)
yodafiles.append("-7-DiJets-%1.1i-C.yoda" % i)
for i in range(1,12) :
yodafiles.append("-13-DiJets-%1.1i-A.yoda" % i)
# for i in range(6,12) :
# yodafiles.append("-13-DiJets-%1.1i-B.yoda" % i)
for f in yodafiles:
file='Rivet-'+args[0]+f
if "-7-Jets" in file or "-7-DiJets" in file or "-7-Bottom" in file :
sqrts = 7000
elif "-13-Jets" in file or "-13-DiJets" in file :
sqrts = 13000
if(file.find("-DiJets-2")>0) :
mass=250
elif(file.find("-DiJets-3")>0) :
mass=500
elif(file.find("-DiJets-4")>0) :
mass=800
elif(file.find("-DiJets-5")>0) :
mass=1000
elif(file.find("-DiJets-6")>0) :
mass=1600
elif(file.find("-DiJets-7")>0) :
mass=2200
elif(file.find("-DiJets-8")>0) :
mass=2800
elif(file.find("-DiJets-9")>0) :
mass=3900
elif(file.find("-DiJets-10")>0) :
mass=4900
elif(file.find("-DiJets-11")>0) :
mass=5900
elif(file.find("-DiJets-1")>0) :
mass=100
elif(file.find("-Bottom-7")>0) :
mass=110
elif(file.find("-Bottom-8")>0) :
mass=370
elif(file.find("-Bottom-9")>0) :
mass=550
elif(file.find("-Jets-1")>0) :
mass=0
if not os.access(file, os.R_OK):
logging.error("%s can not be read" % file)
continue
try:
aos = yoda.read(file)
except:
logging.error("%s can not be parsed as YODA" % file)
continue
## Get histos from this YODA file
for aopath, ao in aos.items() :
if("RAW" in aopath) :continue
if(aopath.find("8817804")>0 or aopath.find("8968497")>0 or
aopath.find("1082936")>0 or aopath.find("I930220")>0 or
aopath.find("1261026")>0 or aopath.find("1090423")>0 or
aopath.find("1268975")>0 or aopath.find("1519995") >0 or
aopath.find("1663452") >0 or
aopath.find("1634970" )>0 or
aopath.find("CMS_2013_I1208923")>0) :
if aopath not in inhistos_mass:
inhistos_mass[aopath] = {}
tmpE = inhistos_mass[aopath]
if sqrts not in tmpE:
tmpE[sqrts] = {}
tmpP = tmpE[sqrts]
if mass not in tmpP:
tmpP[mass] = ao
else:
print (aopath)
print (sqrts,mass,file)
raise Exception("A set with mass = %s already exists" % ( mass))
## Make empty output histos if needed
for hpath,hsets in inhistos_pt.items():
if( hpath.find("8924791")>0 or
hpath.find("8971293")>0 or
hpath.find("8817804")>0 or
hpath.find("8968497")>0 or
(hpath.find("9120041")>0 and (hpath.find("d01")>0 or hpath.find("d02")>0)) or
hpath.find("9126244")>0 or
hpath.find("926145") >0 or
hpath.find("9086218")>0 or
hpath.find("1082936")>0 or
hpath.find("8941262")>0 or
hpath.find("1118269")>0 or
hpath.find("1087342")>0 or
hpath.find("1188891")>0 or
hpath.find("919017")>0 or
hpath.find("9035664")>0 or
hpath.find("1125575")>0 or
hpath.find("1094564")>0 or
hpath.find("I930220")>0 or
hpath.find("S9088458")>0 or
hpath.find("I1273574")>0 or
hpath.find("I1261026")>0 or
hpath.find("I1090423")>0 or
hpath.find("QCD_11_010")>0 or
hpath.find("1298811" )>0 or
hpath.find("I1325553" )>0 or
hpath.find("I1298810" )>0 or
hpath.find("1307243" )>0 or
hpath.find("I1419070")>0 or
hpath.find("I1394679")>0 or
hpath.find("I1487277")>0 or
hpath.find("I1604271")>0 or
hpath.find("I1598460")>0 or
hpath.find("CMS_2013_I1208923")>0 or
hpath.find("1393758")>0 or
hpath.find("ATLAS_2016_CONF_2016_092")>0 or
hpath.find("1111014")>0 or hpath.find("1385107")>0 or hpath.find("I1486238")>0 or
hpath.find("1459051")>0 or hpath.find("1634970")>0 or hpath.find("I1740909")>0 or
hpath.find("1913061")>0) :
title=""
path=""
histo = list(list(hsets.values())[0].values())[0]
if hasattr(histo, 'title'):
title=histo.title()
if hasattr(histo, 'path'):
path=histo.path()
if(type(histo)==yoda.core.Counter) :
outhistos[hpath] = yoda.core.Counter(path,title)
elif(type(histo)==yoda.core.Scatter2D) :
outhistos[hpath] = yoda.core.Scatter2D(path,title)
elif(type(histo)==yoda.core.Profile1D) :
outhistos[hpath] = yoda.core.Profile1D(path,title)
for i in range(0,histo.numBins()) :
outhistos[hpath].addBin(histo.bins()[i].xMin(),
histo.bins()[i].xMax())
elif(type(histo)==yoda.core.Histo1D) :
outhistos[hpath] = yoda.core.Histo1D(path,title)
for i in range(0,histo.numBins()) :
outhistos[hpath].addBin(histo.bins()[i].xMin(),
histo.bins()[i].xMax())
else :
logging.error("Histogram %s is of unknown type" % hpath)
sys.exit(1)
## Make empty output histos if needed
for hpath,hsets in inhistos_mass.items():
if(hpath.find("1268975")>0 or
hpath.find("1634970")>0) :
title=""
path=""
histo = list(list(hsets.values())[0].values())[0]
if hasattr(histo, 'title'):
title=histo.title()
if hasattr(histo, 'path'):
path=histo.path()
if(type(histo)==yoda.core.Counter) :
outhistos[hpath] = yoda.core.Counter(path,title)
elif(type(histo)==yoda.core.Scatter2D) :
outhistos[hpath] = yoda.core.Scatter2D(path,title)
elif(type(histo)==yoda.core.Profile1D) :
outhistos[hpath] = yoda.core.Profile1D(path,title)
for i in range(0,histo.numBins()) :
outhistos[hpath].addBin(histo.bins()[i].xMin(),
histo.bins()[i].xMax())
elif(type(histo)==yoda.core.Histo1D) :
outhistos[hpath] = yoda.core.Histo1D(path,title)
for i in range(0,histo.numBins()) :
outhistos[hpath].addBin(histo.bins()[i].xMin(),
histo.bins()[i].xMax())
else :
logging.error("Histogram %s is of unknown type" % hpath)
sys.exit(1)
logging.info("Processing CMS_2011_S8957746")
useOnePt("/CMS_2011_S8957746/d01-x01-y01", "7000", "80" )
useOnePt("/CMS_2011_S8957746/d02-x01-y01", "7000", "80" )
useOnePt("/CMS_2011_S8957746/d03-x01-y01", "7000", "110" )
useOnePt("/CMS_2011_S8957746/d04-x01-y01", "7000", "110" )
useOnePt("/CMS_2011_S8957746/d05-x01-y01", "7000", "210" )
useOnePt("/CMS_2011_S8957746/d06-x01-y01", "7000", "210" )
logging.info("Processing ATLAS_2010_S8894728")
useOnePt("/ATLAS_2010_S8894728/d01-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d01-x01-y02", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d01-x01-y03", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d02-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d02-x01-y02", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d02-x01-y03", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d03-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d03-x01-y02", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d03-x01-y03", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d04-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d04-x01-y02", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d04-x01-y03", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d05-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d06-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d07-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d08-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d09-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d09-x01-y02", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d09-x01-y03", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d10-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d10-x01-y02", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d10-x01-y03", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d11-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d11-x01-y02", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d11-x01-y03", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d12-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d12-x01-y02", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d12-x01-y03", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d13-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d13-x01-y02", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d13-x01-y03", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d13-x01-y04", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d14-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d14-x01-y02", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d14-x01-y03", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d14-x01-y04", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d15-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d15-x01-y02", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d15-x01-y03", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d15-x01-y04", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d16-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d16-x01-y02", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d16-x01-y03", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d16-x01-y04", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d17-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d17-x01-y02", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d17-x01-y03", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d18-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d18-x01-y02", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d18-x01-y03", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d19-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d19-x01-y02", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d19-x01-y03", "900", "0" )
useOnePt("/ATLAS_2010_S8894728/d20-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d20-x01-y02", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d20-x01-y03", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d21-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8894728/d22-x01-y01", "7000", "0" )
logging.info("Processing ATLAS_2011_S8994773")
useOnePt("/ATLAS_2011_S8994773/d01-x01-y01", "900", "0" )
useOnePt("/ATLAS_2011_S8994773/d02-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2011_S8994773/d03-x01-y01", "900", "0" )
useOnePt("/ATLAS_2011_S8994773/d04-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2011_S8994773/d13-x01-y01", "900", "0" )
useOnePt("/ATLAS_2011_S8994773/d13-x01-y02", "900", "0" )
useOnePt("/ATLAS_2011_S8994773/d13-x01-y03", "900", "0" )
useOnePt("/ATLAS_2011_S8994773/d14-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2011_S8994773/d14-x01-y02", "7000", "0" )
useOnePt("/ATLAS_2011_S8994773/d14-x01-y03", "7000", "0" )
logging.info("Processing ALICE_2010_S8624100")
useOnePt("/ALICE_2010_S8624100/d11-x01-y01", "900", "0" )
useOnePt("/ALICE_2010_S8624100/d12-x01-y01", "900", "0" )
useOnePt("/ALICE_2010_S8624100/d13-x01-y01", "900", "0" )
useOnePt("/ALICE_2010_S8624100/d17-x01-y01","2360", "0" )
useOnePt("/ALICE_2010_S8624100/d18-x01-y01","2360", "0" )
useOnePt("/ALICE_2010_S8624100/d19-x01-y01","2360", "0" )
logging.info("Processing ALICE_2010_S8625980")
useOnePt("/ALICE_2010_S8625980/d03-x01-y01", "7000", "0" )
useOnePt("/ALICE_2010_S8625980/d04-x01-y01", "900", "0" )
useOnePt("/ALICE_2010_S8625980/d05-x01-y01", "2360", "0" )
useOnePt("/ALICE_2010_S8625980/d06-x01-y01", "7000", "0" )
logging.info("Processing ATLAS_2010_S8918562")
useOnePt("/ATLAS_2010_S8918562/d01-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d02-x01-y01", "2360", "0" )
useOnePt("/ATLAS_2010_S8918562/d03-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d04-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d05-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d06-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d07-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d08-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d09-x01-y01", "2360", "0" )
useOnePt("/ATLAS_2010_S8918562/d10-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d11-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d12-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d13-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d14-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d15-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d16-x01-y01", "2360", "0" )
useOnePt("/ATLAS_2010_S8918562/d17-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d18-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d19-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d20-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d21-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d22-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d23-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d24-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d25-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d26-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d27-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d28-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d29-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d30-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d31-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d32-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d33-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d34-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d35-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d36-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d37-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2010_S8918562/d38-x01-y01", "900", "0" )
useOnePt("/ATLAS_2010_S8918562/d39-x01-y01", "7000", "0" )
logging.info("Processing ATLAS_2011_S8971293")
useOnePt("/ATLAS_2011_S8971293/d01-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8971293/d01-x01-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8971293/d01-x01-y03", "7000", "210" )
useOnePt("/ATLAS_2011_S8971293/d01-x01-y04", "7000", "260" )
useOnePt("/ATLAS_2011_S8971293/d01-x01-y05", "7000", "260" )
useOnePt("/ATLAS_2011_S8971293/d01-x01-y06", "7000", "400" )
useOnePt("/ATLAS_2011_S8971293/d01-x01-y07", "7000", "400" )
useOnePt("/ATLAS_2011_S8971293/d01-x01-y08", "7000", "600" )
useOnePt("/ATLAS_2011_S8971293/d01-x01-y09", "7000", "600" )
logging.info("Processing ATLAS_2011_S8924791")
if( not opts.ue) :
useOnePt("/ATLAS_2011_S8924791/d01-x01-y01", "7000", "10" )
useOnePt("/ATLAS_2011_S8924791/d01-x01-y02", "7000", "10" )
useOnePt("/ATLAS_2011_S8924791/d01-x02-y01", "7000", "10" )
useOnePt("/ATLAS_2011_S8924791/d01-x02-y02", "7000", "10" )
useOnePt("/ATLAS_2011_S8924791/d01-x03-y01", "7000", "10" )
useOnePt("/ATLAS_2011_S8924791/d01-x03-y02", "7000", "10" )
useOnePt("/ATLAS_2011_S8924791/d01-x04-y01", "7000", "10" )
useOnePt("/ATLAS_2011_S8924791/d01-x04-y02", "7000", "10" )
useOnePt("/ATLAS_2011_S8924791/d01-x05-y01", "7000", "10" )
useOnePt("/ATLAS_2011_S8924791/d01-x05-y02", "7000", "10" )
useOnePt("/ATLAS_2011_S8924791/d01-x06-y01", "7000", "10" )
useOnePt("/ATLAS_2011_S8924791/d01-x06-y02", "7000", "10" )
else :
useOnePt("/ATLAS_2011_S8924791/d01-x01-y01", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d01-x01-y02", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d01-x02-y01", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d01-x02-y02", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d01-x03-y01", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d01-x03-y02", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d01-x04-y01", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d01-x04-y02", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d01-x05-y01", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d01-x05-y02", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d01-x06-y01", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d01-x06-y02", "7000", "20" )
useOnePt("/ATLAS_2011_S8924791/d02-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d02-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d02-x02-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d02-x02-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d02-x03-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d02-x03-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d02-x04-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d02-x04-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d02-x05-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d02-x05-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d02-x06-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d02-x06-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x02-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x02-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x03-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x03-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x04-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x04-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x05-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x05-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x06-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d03-x06-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S8924791/d04-x01-y01", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d04-x01-y02", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d04-x02-y01", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d04-x02-y02", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d04-x03-y01", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d04-x03-y02", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d04-x04-y01", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d04-x04-y02", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d04-x05-y01", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d04-x05-y02", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d04-x06-y01", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d04-x06-y02", "7000", "80" )
useOnePt("/ATLAS_2011_S8924791/d05-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d05-x01-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d05-x02-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d05-x02-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d05-x03-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d05-x03-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d05-x04-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d05-x04-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d05-x05-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d05-x05-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d05-x06-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d05-x06-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x01-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x02-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x02-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x03-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x03-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x04-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x04-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x05-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x05-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x06-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d06-x06-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S8924791/d07-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d07-x01-y02", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d07-x02-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d07-x02-y02", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d07-x03-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d07-x03-y02", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d07-x04-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d07-x04-y02", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d07-x05-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d07-x05-y02", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d07-x06-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d07-x06-y02", "7000", "210" )
useOnePt("/ATLAS_2011_S8924791/d08-x01-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d08-x01-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d08-x02-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d08-x02-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d08-x03-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d08-x03-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d08-x04-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d08-x04-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d08-x05-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d08-x05-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d08-x06-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d08-x06-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x01-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x01-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x02-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x02-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x03-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x03-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x04-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x04-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x05-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x05-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x06-y01", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d09-x06-y02", "7000", "260" )
useOnePt("/ATLAS_2011_S8924791/d10-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d10-x01-y02", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d10-x02-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d10-x02-y02", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d10-x03-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d10-x03-y02", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d10-x04-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d10-x04-y02", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d10-x05-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d10-x05-y02", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d10-x06-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d10-x06-y02", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x01-y02", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x02-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x02-y02", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x03-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x03-y02", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x04-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x04-y02", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x05-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x05-y02", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x06-y01", "7000", "400" )
useOnePt("/ATLAS_2011_S8924791/d11-x06-y02", "7000", "400" )
logging.info("Processing ATLAS_2010_S8817804")
mergeByPt("/ATLAS_2010_S8817804/d01-x01-y01", "7000")
mergeByPt("/ATLAS_2010_S8817804/d02-x01-y01", "7000")
mergeByPt("/ATLAS_2010_S8817804/d03-x01-y01", "7000")
mergeByPt("/ATLAS_2010_S8817804/d04-x01-y01", "7000")
mergeByPt("/ATLAS_2010_S8817804/d05-x01-y01", "7000")
mergeByPt("/ATLAS_2010_S8817804/d06-x01-y01", "7000")
mergeByPt("/ATLAS_2010_S8817804/d07-x01-y01", "7000")
mergeByPt("/ATLAS_2010_S8817804/d08-x01-y01", "7000")
mergeByPt("/ATLAS_2010_S8817804/d09-x01-y01", "7000")
mergeByPt("/ATLAS_2010_S8817804/d10-x01-y01", "7000")
mergeByMass("/ATLAS_2010_S8817804/d11-x01-y01", "7000")
mergeByMass("/ATLAS_2010_S8817804/d12-x01-y01", "7000")
mergeByMass("/ATLAS_2010_S8817804/d13-x01-y01", "7000")
mergeByMass("/ATLAS_2010_S8817804/d14-x01-y01", "7000")
mergeByMass("/ATLAS_2010_S8817804/d15-x01-y01", "7000")
mergeByMass("/ATLAS_2010_S8817804/d16-x01-y01", "7000")
mergeByMass("/ATLAS_2010_S8817804/d17-x01-y01", "7000")
mergeByMass("/ATLAS_2010_S8817804/d18-x01-y01", "7000")
mergeByMass("/ATLAS_2010_S8817804/d19-x01-y01", "7000")
mergeByMass("/ATLAS_2010_S8817804/d20-x01-y01", "7000")
useOneMass("/ATLAS_2010_S8817804/d21-x01-y01", "7000", "250" )
useOneMass("/ATLAS_2010_S8817804/d22-x01-y01", "7000", "250" )
useOneMass("/ATLAS_2010_S8817804/d23-x01-y01", "7000", "650" )
useOneMass("/ATLAS_2010_S8817804/d24-x01-y01", "7000", "250" )
useOneMass("/ATLAS_2010_S8817804/d25-x01-y01", "7000", "250" )
useOneMass("/ATLAS_2010_S8817804/d26-x01-y01", "7000", "650" )
logging.info("Processing ATLAS_2011_I930220")
mergeByPt("/ATLAS_2011_I930220/d01-x01-y01", "7000" )
mergeByPt("/ATLAS_2011_I930220/d02-x01-y01", "7000" )
mergeByPt("/ATLAS_2011_I930220/d03-x01-y01", "7000" )
mergeByPt("/ATLAS_2011_I930220/d04-x01-y01", "7000" )
mergeByPt("/ATLAS_2011_I930220/d05-x01-y01", "7000" )
mergeByPt("/ATLAS_2011_I930220/d06-x01-y01", "7000" )
mergeByMass("/ATLAS_2011_I930220/d07-x01-y01", "7000")
useOneMass("/ATLAS_2011_I930220/d08-x01-y01", "7000", "110" )
useOneMass("/ATLAS_2011_I930220/d09-x01-y01", "7000", "110" )
useOneMass("/ATLAS_2011_I930220/d10-x01-y01", "7000", "370" )
logging.info("Processing ATLAS_2012_I1082936")
mergeByPt("/ATLAS_2012_I1082936/d01-x01-y01", "7000")
mergeByPt("/ATLAS_2012_I1082936/d01-x01-y02", "7000")
mergeByPt("/ATLAS_2012_I1082936/d01-x01-y03", "7000")
mergeByPt("/ATLAS_2012_I1082936/d01-x01-y04", "7000")
mergeByPt("/ATLAS_2012_I1082936/d01-x01-y05", "7000")
mergeByPt("/ATLAS_2012_I1082936/d01-x01-y06", "7000")
mergeByPt("/ATLAS_2012_I1082936/d01-x01-y07", "7000")
mergeByPt("/ATLAS_2012_I1082936/d02-x01-y01", "7000")
mergeByPt("/ATLAS_2012_I1082936/d02-x01-y02", "7000")
mergeByPt("/ATLAS_2012_I1082936/d02-x01-y03", "7000")
mergeByPt("/ATLAS_2012_I1082936/d02-x01-y04", "7000")
mergeByPt("/ATLAS_2012_I1082936/d02-x01-y05", "7000")
mergeByPt("/ATLAS_2012_I1082936/d02-x01-y06", "7000")
mergeByPt("/ATLAS_2012_I1082936/d02-x01-y07", "7000")
mergeByMass("/ATLAS_2012_I1082936/d03-x01-y01", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d03-x01-y02", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d03-x01-y03", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d03-x01-y04", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d03-x01-y05", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d03-x01-y06", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d03-x01-y07", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d03-x01-y08", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d03-x01-y09", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d04-x01-y01", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d04-x01-y02", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d04-x01-y03", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d04-x01-y04", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d04-x01-y05", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d04-x01-y06", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d04-x01-y07", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d04-x01-y08", "7000", 1000.)
mergeByMass("/ATLAS_2012_I1082936/d04-x01-y09", "7000", 1000.)
logging.info("Processing CMS_2011_S8968497")
useOneMass("/CMS_2011_S8968497/d01-x01-y01", "7000", "1700" )
useOneMass("/CMS_2011_S8968497/d02-x01-y01", "7000", "1700" )
useOneMass("/CMS_2011_S8968497/d03-x01-y01", "7000", "1100" )
useOneMass("/CMS_2011_S8968497/d04-x01-y01", "7000", "1100" )
useOneMass("/CMS_2011_S8968497/d05-x01-y01", "7000", "650" )
useOneMass("/CMS_2011_S8968497/d06-x01-y01", "7000", "650" )
useOneMass("/CMS_2011_S8968497/d07-x01-y01", "7000", "250" )
useOneMass("/CMS_2011_S8968497/d08-x01-y01", "7000", "250" )
useOneMass("/CMS_2011_S8968497/d09-x01-y01", "7000", "250" )
logging.info("Processing ATLAS_2011_S9126244")
mergeByPt("/ATLAS_2011_S9126244/d01-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9126244/d01-x01-y02", "7000")
mergeByPt("/ATLAS_2011_S9126244/d02-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9126244/d02-x01-y02", "7000")
mergeByPt("/ATLAS_2011_S9126244/d03-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9126244/d03-x01-y02", "7000")
mergeByPt("/ATLAS_2011_S9126244/d04-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9126244/d04-x01-y02", "7000")
mergeByPt("/ATLAS_2011_S9126244/d05-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9126244/d05-x01-y02", "7000")
useOnePt("/ATLAS_2011_S9126244/d06-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S9126244/d06-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S9126244/d07-x01-y01", "7000", "80" )
useOnePt("/ATLAS_2011_S9126244/d07-x01-y02", "7000", "80" )
useOnePt("/ATLAS_2011_S9126244/d08-x01-y01", "7000", "80" )
useOnePt("/ATLAS_2011_S9126244/d08-x01-y02", "7000", "80" )
useOnePt("/ATLAS_2011_S9126244/d09-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d09-x01-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d10-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d10-x01-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d11-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d11-x01-y02", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d12-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d12-x01-y02", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d13-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S9126244/d13-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S9126244/d14-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S9126244/d14-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S9126244/d15-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d15-x01-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d16-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d16-x01-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d17-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d17-x01-y02", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d18-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d18-x01-y02", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d19-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S9126244/d20-x01-y01", "7000", "80" )
useOnePt("/ATLAS_2011_S9126244/d21-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d22-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d23-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d24-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d25-x01-y01", "7000", "210" )
mergeByPt("/ATLAS_2011_S9126244/d26-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9126244/d26-x01-y02", "7000")
mergeByPt("/ATLAS_2011_S9126244/d27-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9126244/d27-x01-y02", "7000")
mergeByPt("/ATLAS_2011_S9126244/d28-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9126244/d28-x01-y02", "7000")
mergeByPt("/ATLAS_2011_S9126244/d29-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9126244/d29-x01-y02", "7000")
useOnePt("/ATLAS_2011_S9126244/d30-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S9126244/d31-x01-y01", "7000", "80" )
useOnePt("/ATLAS_2011_S9126244/d32-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d33-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d34-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d35-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d36-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d37-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2011_S9126244/d37-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2011_S9126244/d38-x01-y01", "7000", "80" )
useOnePt("/ATLAS_2011_S9126244/d38-x01-y02", "7000", "80" )
useOnePt("/ATLAS_2011_S9126244/d39-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d39-x01-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d40-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d40-x01-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d41-x01-y01", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d41-x01-y02", "7000", "110" )
useOnePt("/ATLAS_2011_S9126244/d42-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d42-x01-y02", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d43-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2011_S9126244/d43-x01-y02", "7000", "210" )
# CMS_2011_S9120041 UE analysis
logging.info("Processing CMS_2011_S9120041")
mergeByPt("/CMS_2011_S9120041/d01-x01-y01", "7000")
mergeByPt("/CMS_2011_S9120041/d02-x01-y01", "7000")
if(opts.ue) :
useOnePt("/CMS_2011_S9120041/d03-x01-y01", "900", "0" )
useOnePt("/CMS_2011_S9120041/d04-x01-y01", "900", "0" )
useOnePt("/CMS_2011_S9120041/d05-x01-y01", "7000", "0" )
useOnePt("/CMS_2011_S9120041/d06-x01-y01", "7000", "0" )
useOnePt("/CMS_2011_S9120041/d07-x01-y01", "7000", "0" )
useOnePt("/CMS_2011_S9120041/d11-x01-y01", "900", "0" )
useOnePt("/CMS_2011_S9120041/d12-x01-y01", "900", "0" )
useOnePt("/CMS_2011_S9120041/d13-x01-y01", "900", "0" )
useOnePt("/CMS_2011_S9120041/d08-x01-y01", "7000", "20" )
useOnePt("/CMS_2011_S9120041/d09-x01-y01", "7000", "20" )
useOnePt("/CMS_2011_S9120041/d10-x01-y01", "7000", "20" )
else :
useOnePt("/CMS_2011_S9120041/d08-x01-y01", "7000", "10" )
useOnePt("/CMS_2011_S9120041/d09-x01-y01", "7000", "10" )
useOnePt("/CMS_2011_S9120041/d10-x01-y01", "7000", "10" )
# CMS dijet decorrelation
logging.info("Processing CMS_2011_S8950903")
useOnePt("/CMS_2011_S8950903/d01-x01-y01", "7000", "80" )
useOnePt("/CMS_2011_S8950903/d02-x01-y01", "7000", "110" )
useOnePt("/CMS_2011_S8950903/d03-x01-y01", "7000", "110" )
useOnePt("/CMS_2011_S8950903/d04-x01-y01", "7000", "210" )
useOnePt("/CMS_2011_S8950903/d05-x01-y01", "7000", "260" )
# CMS jet cross section
logging.info("Processing CMS_2011_S9086218")
mergeByPt("/CMS_2011_S9086218/d01-x01-y01", "7000")
mergeByPt("/CMS_2011_S9086218/d02-x01-y01", "7000")
mergeByPt("/CMS_2011_S9086218/d03-x01-y01", "7000")
mergeByPt("/CMS_2011_S9086218/d04-x01-y01", "7000")
mergeByPt("/CMS_2011_S9086218/d05-x01-y01", "7000")
mergeByPt("/CMS_2011_S9086218/d06-x01-y01", "7000")
# CMS 2/3 jet cross section ratio
logging.info("Processing CMS_2011_S9086218")
mergeByPt("/CMS_2011_S9088458/d01-x01-y01", "7000",500.)
# ATLAS track jet
logging.info("Processing ATLAS_2011_I919017")
for d in range(1,3) :
for y in range(1,5) :
mergeByPt("/ATLAS_2011_I919017/d0%s-x01-y0%s" % (d,y), "7000")
if( opts.ue) :
for x in range(2,6) :
for y in ["01","02","06","07","11","12","16","17","21","22"] :
useOnePt("/ATLAS_2011_I919017/d0%s-x0%s-y%s" % (d,x,y), "7000", "0" )
for y in ["03","04","08","09","13","14","18","19","23","24"] :
useOnePt("/ATLAS_2011_I919017/d0%s-x0%s-y%s" % (d,x,y), "7000", "4" )
for y in range(5,30,5) :
useOnePt("/ATLAS_2011_I919017/d0%s-x%02d-y%02d" % (d,x,y) , "7000", "20" )
else :
for x in range(2,6) :
for y in range(5,30,5) :
useOnePt("/ATLAS_2011_I919017/d0%s-x%02d-y%02d" % (d,x,y) , "7000", "10" )
logging.info("Processing ATLAS_2011_I926145")
mergeByPt("/ATLAS_2011_I926145/d01-x01-y01", "7000",1.5)
mergeByPt("/ATLAS_2011_I926145/d02-x01-y01", "7000",1.5)
mergeByPt("/ATLAS_2011_I926145/d03-x01-y01", "7000",1.5)
logging.info("Processing CMS_2011_S8941262")
useOnePt("/CMS_2011_S8941262/d01-x01-y01", "7000", "10" )
useOnePt("/CMS_2011_S8941262/d03-x01-y01", "7000", "10" )
mergeByPt("/CMS_2011_S8941262/d02-x01-y01", "7000",1.5)
logging.info("Processing CMS_2011_S8973270")
useOnePt("/CMS_2011_S8973270/d01-x01-y01", "7000", "70" )
useOnePt("/CMS_2011_S8973270/d02-x01-y01", "7000", "100" )
useOnePt("/CMS_2011_S8973270/d03-x01-y01", "7000", "130" )
useOnePt("/CMS_2011_S8973270/d04-x01-y01", "7000", "70" )
useOnePt("/CMS_2011_S8973270/d05-x01-y01", "7000", "100" )
useOnePt("/CMS_2011_S8973270/d06-x01-y01", "7000", "130" )
logging.info("Processing ATLAS_2012_I1082009")
useOnePt("/ATLAS_2012_I1082009/d08-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2012_I1082009/d09-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2012_I1082009/d10-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2012_I1082009/d11-x01-y01", "7000", "80" )
useOnePt("/ATLAS_2012_I1082009/d12-x01-y01", "7000", "80" )
useOnePt("/ATLAS_2012_I1082009/d13-x01-y01", "7000", "40" )
logging.info("Processing ATLAS_2012_I1118269")
mergeByPt("/ATLAS_2012_I1118269/d01-x01-y01", "7000")
useOnePt("/ATLAS_2012_I1118269/d02-x01-y01", "7000", "10" )
logging.info("Processing ATLAS_2012_I1188891")
mergeByPt("/ATLAS_2012_I1188891/d01-x01-y01", "7000")
mergeByPt("/ATLAS_2012_I1188891/d02-x01-y01", "7000")
mergeByPt("/ATLAS_2012_I1188891/d03-x01-y01", "7000")
mergeByPt("/ATLAS_2012_I1188891/d04-x01-y01", "7000")
mergeByPt("/ATLAS_2012_I1188891/d05-x01-y01", "7000")
mergeByPt("/ATLAS_2012_I1188891/d06-x01-y01", "7000")
logging.info("Processing CMS_2012_I1087342")
mergeByPt("/CMS_2012_I1087342/d01-x01-y01", "7000")
mergeByPt("/CMS_2012_I1087342/d02-x01-y01", "7000")
mergeByPt("/CMS_2012_I1087342/d03-x01-y01", "7000")
logging.info("Processing CMS_2012_PAS_QCD_11_010")
mergeByPt("/CMS_2012_PAS_QCD_11_010/d01-x01-y01", "7000")
mergeByPt("/CMS_2012_PAS_QCD_11_010/d02-x01-y01", "7000")
mergeByPt("/CMS_2012_PAS_QCD_11_010/d03-x01-y01", "7000")
mergeByPt("/CMS_2012_PAS_QCD_11_010/d04-x01-y01", "7000")
logging.info("Processing ATLAS_2011_S9035664")
mergeByPt("/ATLAS_2011_S9035664/d11-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9035664/d12-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9035664/d13-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9035664/d14-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9035664/d15-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9035664/d16-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9035664/d17-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9035664/d18-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9035664/d20-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9035664/d21-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9035664/d22-x01-y01", "7000")
mergeByPt("/ATLAS_2011_S9035664/d23-x01-y01", "7000")
logging.info("Processing ATLAS_2012_I1125575")
mergeByPt("/ATLAS_2012_I1125575/d01-x01-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d01-x01-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d01-x02-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d01-x02-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d01-x03-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d01-x03-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d01-x04-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d01-x04-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d01-x05-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d01-x05-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d02-x01-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d02-x01-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d02-x02-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d02-x02-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d02-x03-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d02-x03-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d02-x04-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d02-x04-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d02-x05-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d02-x05-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d03-x01-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d03-x01-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d03-x02-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d03-x02-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d03-x03-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d03-x03-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d03-x04-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d03-x04-y02", "7000")
mergeByPt("/ATLAS_2012_I1125575/d03-x05-y01", "7000")
mergeByPt("/ATLAS_2012_I1125575/d03-x05-y02", "7000")
for d in range(4,7) :
for x in range(1,6) :
if(opts.ue) :
for y in range(1,9) :
useOnePt("/ATLAS_2012_I1125575/d0%s-x0%s-y0%s" % (d,x,y), "7000", "0" )
for y in ["09","10","11","12","13","14","15","16"] :
useOnePt("/ATLAS_2012_I1125575/d0%s-x0%s-y%s" % (d,x,y), "7000", "0" )
for y in range(17,19) :
useOnePt("/ATLAS_2012_I1125575/d0%s-x0%s-y%s" % (d,x,y), "7000", "20" )
else :
for y in range(17,19) :
useOnePt("/ATLAS_2012_I1125575/d0%s-x0%s-y%s" % (d,x,y), "7000", "10" )
for y in range(19,21) :
useOnePt("/ATLAS_2012_I1125575/d0%s-x0%s-y%s" % (d,x,y), "7000", "40" )
# ATLAS_2012_I1094564
useOnePt("/ATLAS_2012_I1094564/d01-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2012_I1094564/d02-x01-y01", "7000", "260" )
useOnePt("/ATLAS_2012_I1094564/d03-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d04-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d05-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2012_I1094564/d06-x01-y01", "7000", "260" )
useOnePt("/ATLAS_2012_I1094564/d07-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d08-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d09-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2012_I1094564/d10-x01-y01", "7000", "260" )
useOnePt("/ATLAS_2012_I1094564/d11-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d12-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d13-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2012_I1094564/d14-x01-y01", "7000", "260" )
useOnePt("/ATLAS_2012_I1094564/d15-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d16-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d17-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2012_I1094564/d18-x01-y01", "7000", "260" )
useOnePt("/ATLAS_2012_I1094564/d19-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d20-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d21-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2012_I1094564/d22-x01-y01", "7000", "260" )
useOnePt("/ATLAS_2012_I1094564/d23-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d24-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d25-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2012_I1094564/d26-x01-y01", "7000", "260" )
useOnePt("/ATLAS_2012_I1094564/d27-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d28-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d29-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2012_I1094564/d30-x01-y01", "7000", "260" )
useOnePt("/ATLAS_2012_I1094564/d31-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d32-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d33-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2012_I1094564/d34-x01-y01", "7000", "260" )
useOnePt("/ATLAS_2012_I1094564/d35-x01-y01", "7000", "400" )
useOnePt("/ATLAS_2012_I1094564/d36-x01-y01", "7000", "400" )
logging.info("Processing CMS_2013_I1224539_DIJET")
useOnePt("/CMS_2013_I1224539_DIJET/d01-x01-y01", "7000", "210" )
useOnePt("/CMS_2013_I1224539_DIJET/d02-x01-y01", "7000", "260" )
useOnePt("/CMS_2013_I1224539_DIJET/d03-x01-y01", "7000", "400" )
useOnePt("/CMS_2013_I1224539_DIJET/d04-x01-y01", "7000", "400" )
useOnePt("/CMS_2013_I1224539_DIJET/d05-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d06-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d07-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d08-x01-y01", "7000", "210" )
useOnePt("/CMS_2013_I1224539_DIJET/d09-x01-y01", "7000", "260" )
useOnePt("/CMS_2013_I1224539_DIJET/d10-x01-y01", "7000", "400" )
useOnePt("/CMS_2013_I1224539_DIJET/d11-x01-y01", "7000", "400" )
useOnePt("/CMS_2013_I1224539_DIJET/d12-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d13-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d14-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d15-x01-y01", "7000", "210" )
useOnePt("/CMS_2013_I1224539_DIJET/d16-x01-y01", "7000", "260" )
useOnePt("/CMS_2013_I1224539_DIJET/d17-x01-y01", "7000", "400" )
useOnePt("/CMS_2013_I1224539_DIJET/d18-x01-y01", "7000", "400" )
useOnePt("/CMS_2013_I1224539_DIJET/d19-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d20-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d21-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d22-x01-y01", "7000", "210" )
useOnePt("/CMS_2013_I1224539_DIJET/d23-x01-y01", "7000", "260" )
useOnePt("/CMS_2013_I1224539_DIJET/d24-x01-y01", "7000", "400" )
useOnePt("/CMS_2013_I1224539_DIJET/d25-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d26-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d27-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1224539_DIJET/d28-x01-y01", "7000", "600" )
useOnePt("/CMS_2013_I1273574/d01-x01-y01", "7000", "80" )
mergeByPt("/CMS_2013_I1273574/d02-x01-y01", "7000",1.)
useOnePt("/CMS_2013_I1273574/d03-x01-y01", "7000", "80" )
useOnePt("/CMS_2013_I1273574/d04-x01-y01", "7000", "80" )
useOnePt("/CMS_2013_I1273574/d05-x01-y01", "7000", "80" )
useOnePt("/CMS_2013_I1273574/d06-x01-y01", "7000", "80" )
mergeByPt("/CMS_2013_I1273574/d07-x01-y01", "7000",1.)
useOnePt("/CMS_2013_I1273574/d08-x01-y01", "7000", "80" )
mergeByPt("/CMS_2013_I1273574/d09-x01-y01", "7000",1.)
useOnePt("/CMS_2013_I1273574/d10-x01-y01", "7000", "80" )
mergeByPt("/CMS_2013_I1273574/d11-x01-y01", "7000",1.)
useOnePt("/CMS_2013_I1261026/d01-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d02-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d03-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d04-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d05-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d06-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d07-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d08-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d09-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d10-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d11-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d12-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d13-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d14-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d15-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d16-x01-y01", "7000", "0" )
useOnePt("/CMS_2013_I1261026/d17-x01-y01", "7000", "0" )
logging.info("Processing CMS_2012_I1090423")
useOneMass("/CMS_2012_I1090423/d01-x01-y01", "7000", "2900" )
useOneMass("/CMS_2012_I1090423/d02-x01-y01", "7000", "2300" )
useOneMass("/CMS_2012_I1090423/d03-x01-y01", "7000", "1700" )
useOneMass("/CMS_2012_I1090423/d04-x01-y01", "7000", "1100" )
useOneMass("/CMS_2012_I1090423/d05-x01-y01", "7000", "1100" )
useOneMass("/CMS_2012_I1090423/d06-x01-y01", "7000", "650" )
useOneMass("/CMS_2012_I1090423/d07-x01-y01", "7000", "650" )
useOneMass("/CMS_2012_I1090423/d08-x01-y01", "7000", "250" )
useOneMass("/CMS_2012_I1090423/d09-x01-y01", "7000", "250" )
logging.info("Processing ATLAS_2014_I1298811")
mergeByPt("/ATLAS_2014_I1298811/d01-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1298811/d01-x01-y02", "7000")
mergeByPt("/ATLAS_2014_I1298811/d02-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1298811/d02-x01-y02", "7000")
mergeByPt("/ATLAS_2014_I1298811/d03-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1298811/d03-x01-y02", "7000")
mergeByPt("/ATLAS_2014_I1298811/d04-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1298811/d04-x01-y02", "7000")
mergeByPt("/ATLAS_2014_I1298811/d05-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1298811/d05-x01-y02", "7000")
mergeByPt("/ATLAS_2014_I1298811/d06-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1298811/d06-x01-y02", "7000")
mergeByPt("/ATLAS_2014_I1298811/d07-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1298811/d07-x01-y02", "7000")
mergeByPt("/ATLAS_2014_I1298811/d08-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1298811/d08-x01-y02", "7000")
mergeByPt("/ATLAS_2014_I1298811/d09-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1298811/d09-x01-y02", "7000")
mergeByPt("/ATLAS_2014_I1298811/d10-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1298811/d10-x01-y02", "7000")
useOnePt("/ATLAS_2014_I1298811/d11-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2014_I1298811/d12-x01-y01", "7000", "0" )
useOnePt("/ATLAS_2014_I1298811/d13-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d13-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d14-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d14-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d15-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d15-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d25-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d25-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d26-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d26-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d27-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d27-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d16-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d16-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d17-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d17-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d18-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d18-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d28-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d28-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d29-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d29-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d30-x01-y01", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d30-x01-y02", "7000", "4" )
useOnePt("/ATLAS_2014_I1298811/d19-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d19-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d20-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d20-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d21-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d21-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d31-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d31-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d32-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d32-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d33-x01-y01", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d33-x01-y02", "7000", "40" )
useOnePt("/ATLAS_2014_I1298811/d22-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2014_I1298811/d22-x01-y02", "7000", "210" )
useOnePt("/ATLAS_2014_I1298811/d23-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2014_I1298811/d23-x01-y02", "7000", "210" )
useOnePt("/ATLAS_2014_I1298811/d24-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2014_I1298811/d24-x01-y02", "7000", "210" )
useOnePt("/ATLAS_2014_I1298811/d34-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2014_I1298811/d34-x01-y02", "7000", "210" )
useOnePt("/ATLAS_2014_I1298811/d35-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2014_I1298811/d35-x01-y02", "7000", "210" )
useOnePt("/ATLAS_2014_I1298811/d36-x01-y01", "7000", "210" )
useOnePt("/ATLAS_2014_I1298811/d36-x01-y02", "7000", "210" )
logging.info("Processing ATLAS_2014_I1268975")
mergeByMass("/ATLAS_2014_I1268975/d01-x01-y01", "7000", 1000.)
mergeByMass("/ATLAS_2014_I1268975/d01-x01-y02", "7000", 1000.)
mergeByMass("/ATLAS_2014_I1268975/d01-x01-y03", "7000", 1000.)
mergeByMass("/ATLAS_2014_I1268975/d01-x01-y04", "7000", 1000.)
mergeByMass("/ATLAS_2014_I1268975/d01-x01-y05", "7000", 1000.)
mergeByMass("/ATLAS_2014_I1268975/d01-x01-y06", "7000", 1000.)
mergeByMass("/ATLAS_2014_I1268975/d02-x01-y01", "7000", 1000.)
mergeByMass("/ATLAS_2014_I1268975/d02-x01-y02", "7000", 1000.)
mergeByMass("/ATLAS_2014_I1268975/d02-x01-y03", "7000", 1000.)
mergeByMass("/ATLAS_2014_I1268975/d02-x01-y04", "7000", 1000.)
mergeByMass("/ATLAS_2014_I1268975/d02-x01-y05", "7000", 1000.)
mergeByMass("/ATLAS_2014_I1268975/d02-x01-y06", "7000", 1000.)
logging.info("Processing ATLAS_2014_I1307243")
useOnePt( "/ATLAS_2014_I1307243/d01-x01-y01", "7000", "80" )
mergeByPt("/ATLAS_2014_I1307243/d02-x01-y01", "7000")
useOnePt( "/ATLAS_2014_I1307243/d03-x01-y01", "7000", "80" )
mergeByPt("/ATLAS_2014_I1307243/d04-x01-y01", "7000")
useOnePt( "/ATLAS_2014_I1307243/d05-x01-y01", "7000", "80" )
mergeByPt("/ATLAS_2014_I1307243/d06-x01-y01", "7000")
useOnePt( "/ATLAS_2014_I1307243/d07-x01-y01", "7000", "80" )
mergeByPt("/ATLAS_2014_I1307243/d08-x01-y01", "7000")
useOnePt( "/ATLAS_2014_I1307243/d09-x01-y01", "7000", "80" )
mergeByPt("/ATLAS_2014_I1307243/d10-x01-y01", "7000")
useOnePt( "/ATLAS_2014_I1307243/d11-x01-y01", "7000", "80" )
mergeByPt("/ATLAS_2014_I1307243/d12-x01-y01", "7000")
useOnePt( "/ATLAS_2014_I1307243/d13-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d14-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d15-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d16-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d17-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d18-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d19-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d20-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d21-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d22-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d23-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d24-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d25-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d26-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d27-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d28-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d29-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d30-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d31-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d32-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d33-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d34-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d35-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d36-x01-y01", "7000", "80" )
useOnePt( "/ATLAS_2014_I1307243/d37-x01-y01", "7000", "80" )
mergeByPt("/ATLAS_2014_I1307243/d38-x01-y01", "7000")
useOnePt( "/ATLAS_2014_I1307243/d39-x01-y01", "7000", "80" )
mergeByPt("/ATLAS_2014_I1307243/d40-x01-y01", "7000")
logging.info("Processing ATLAS_2014_I1325553")
mergeByPt("/ATLAS_2014_I1325553/d01-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1325553/d02-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1325553/d03-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1325553/d04-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1325553/d05-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1325553/d06-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1325553/d07-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1325553/d08-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1325553/d09-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1325553/d10-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1325553/d11-x01-y01", "7000")
mergeByPt("/ATLAS_2014_I1325553/d12-x01-y01", "7000")
logging.info("Processing ATLAS_2016_I1419070")
for i in range(1,13) :
if(i<10) :
mergeByPt("/ATLAS_2016_I1419070/d0%s-x01-y01" % i, "8000")
else :
mergeByPt("/ATLAS_2016_I1419070/d%s-x01-y01" % i, "8000")
# remake differences and sums
for ihist in range(1,4) :
if not ("/ATLAS_2016_I1419070/d0%s-x01-y01" % ihist) in outhistos :
continue
h1 = outhistos["/ATLAS_2016_I1419070/d0%s-x01-y01" % ihist ]
h2 = outhistos["/ATLAS_2016_I1419070/d0%s-x01-y01" % (ihist+3)]
sstring = "/ATLAS_2016_I1419070/d%s-x01-y01" % (9+ihist)
dstring = "/ATLAS_2016_I1419070/d0%s-x01-y01" % (6+ihist)
hdiff = yoda.Scatter2D(dstring,dstring)
hsum = yoda.Scatter2D(sstring,sstring)
outhistos[dstring]= hdiff
outhistos[sstring]= hsum
for nbin in range(0,h2.numBins()) :
bsum = h1.bins()[nbin]+h2.bins()[nbin]
try:
ydiff = h2.bins()[nbin].mean()-h1.bins()[nbin].mean()
except:
ydiff = 0
try:
ysum = bsum.mean()
bstderr = bsum.stdErr()
except:
ysum = 0
bstderr = 0
try:
yerr = math.sqrt(h1.bins()[nbin].stdErr()**2+h2.bins()[nbin].stdErr()**2)
except:
yerr = 0
x = h1.bins()[nbin].xMid()
xerr = 0.5*h1.bins()[nbin].xWidth()
hdiff.addPoint(x,ydiff,xerr,yerr)
hsum.addPoint(x,ysum ,xerr,bstderr)
logging.info("Processing ATLAS_2015_I1394679")
for i in range(1,5) :
mergeByPt("/ATLAS_2015_I1394679/d0%s-x01-y01" % i, "8000")
for i in range(5,11) :
if(i<10) :
useOnePt( "/ATLAS_2015_I1394679/d0%s-x01-y01" % i, "8000", "110" )
else :
useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % i, "8000", "110" )
for i in range(0,4) :
useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (11+4*i), "8000", "110" )
useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (12+4*i), "8000", "260" )
useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (13+4*i), "8000", "600" )
useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (14+4*i), "8000", "900" )
for i in range(0,5) :
useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (27+4*i), "8000", "110" )
useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (28+4*i), "8000", "260" )
useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (29+4*i), "8000", "400" )
useOnePt( "/ATLAS_2015_I1394679/d%s-x01-y01" % (30+4*i), "8000", "400" )
logging.info("Processing CMS_2013_I1208923")
for i in range(1,6) :
mergeByPt ("/CMS_2013_I1208923/d01-x01-y0%s" % i, "7000")
mergeByMass("/CMS_2013_I1208923/d02-x01-y0%s" % i, "7000", 1.)
logging.info("Processing CMS_2014_I1298810")
for i in range(1,19) :
if(i<10) :
mergeByPt("/CMS_2014_I1298810/d0"+str(i)+"-x01-y01", "7000")
else :
mergeByPt("/CMS_2014_I1298810/d"+str(i)+"-x01-y01", "7000")
logging.info("Processing CMS_2014_I1305624")
for x in range(1,6) :
useOnePt( "/CMS_2014_I1305624/d01-x%02d-y01" % x, "7000", "110" )
useOnePt( "/CMS_2014_I1305624/d01-x%02d-y02" % x, "7000", "110" )
useOnePt( "/CMS_2014_I1305624/d01-x%02d-y03" % x, "7000", "260" )
useOnePt( "/CMS_2014_I1305624/d01-x%02d-y04" % x, "7000", "260" )
useOnePt( "/CMS_2014_I1305624/d01-x%02d-y05" % x, "7000", "400" )
logging.info("Processing ATLAS_2011_I929691")
for x in range(0,3) :
useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 1), "7000", "20" )
useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 2), "7000", "40" )
useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 3), "7000", "40" )
useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 4), "7000", "80" )
useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 5), "7000", "110" )
useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 6), "7000", "110" )
useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 7), "7000", "210" )
useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 8), "7000", "260" )
useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+ 9), "7000", "260" )
useOnePt( "/ATLAS_2011_I929691/d%02d-x01-y01" % (10*x+10), "7000", "400" )
logging.info("Processing ATLAS_2015_I1393758")
for i in range(1,13) :
mergeByPt("/ATLAS_2015_I1393758/d%02d-x01-y01" % i, "8000")
logging.info("Processing CMS_2016_I1459051")
for i in range(1,15) :
mergeByPt("/CMS_2016_I1459051/d%02d-x01-y01" % i, "13000")
logging.info("Processing ATLAS_2016_CONF_2016_092")
for i in range(1,7) :
mergeByPt("/ATLAS_2016_CONF_2016_092/d%02d-x01-y01" % i, "13000")
logging.info("Processing ATLAS_2017_I1609253")
useOnePt( "/ATLAS_2017_I1609253/d01-x01-y01", "8000", "260" )
useOnePt( "/ATLAS_2017_I1609253/d02-x01-y01", "8000", "260" )
useOnePt( "/ATLAS_2017_I1609253/d03-x01-y01", "8000", "260" )
useOnePt( "/ATLAS_2017_I1609253/d04-x01-y01", "8000", "260" )
useOnePt( "/ATLAS_2017_I1609253/d05-x01-y01", "8000", "400" )
useOnePt( "/ATLAS_2017_I1609253/d06-x01-y01", "8000", "400" )
useOnePt( "/ATLAS_2017_I1609253/d07-x01-y01", "8000", "400" )
useOnePt( "/ATLAS_2017_I1609253/d08-x01-y01", "8000", "400" )
useOnePt( "/ATLAS_2017_I1609253/d09-x01-y01", "8000", "400" )
useOnePt( "/ATLAS_2017_I1609253/d10-x01-y01", "8000", "400" )
useOnePt( "/ATLAS_2017_I1609253/d11-x01-y01", "8000", "600" )
useOnePt( "/ATLAS_2017_I1609253/d12-x01-y01", "8000", "600" )
logging.info("Processing CMS_2016_I1487277")
mergeByPt("/CMS_2016_I1487277/d01-x01-y01", "8000")
mergeByPt("/CMS_2016_I1487277/d02-x01-y01", "8000")
mergeByPt("/CMS_2016_I1487277/d03-x01-y01", "8000")
mergeByPt("/CMS_2016_I1487277/d04-x01-y01", "8000")
mergeByPt("/CMS_2016_I1487277/d05-x01-y01", "8000")
mergeByPt("/CMS_2016_I1487277/d06-x01-y01", "8000")
mergeByPt("/CMS_2016_I1487277/d07-x01-y01", "8000")
logging.info("Processing CMS_2016_I1421646")
useOnePt( "/CMS_2016_I1421646/d01-x01-y01", "8000", "210" )
useOnePt( "/CMS_2016_I1421646/d02-x01-y01", "8000", "260" )
useOnePt( "/CMS_2016_I1421646/d03-x01-y01", "8000", "400" )
useOnePt( "/CMS_2016_I1421646/d04-x01-y01", "8000", "400" )
useOnePt( "/CMS_2016_I1421646/d05-x01-y01", "8000", "600" )
useOnePt( "/CMS_2016_I1421646/d06-x01-y01", "8000", "900" )
useOnePt( "/CMS_2016_I1421646/d07-x01-y01", "8000", "900" )
logging.info("Processing CMS_2017_I1605749")
for i in [1,2,3,4,5,6,7,8,9,10,13,16] :
useOnePt("/CMS_2017_I1605749/d%02d-x01-y01" % i, "8000", "400" )
for i in [11,14,17]:
useOnePt("/CMS_2017_I1605749/d%02d-x01-y01" % i, "8000", "600" )
for i in [12,15,18]:
useOnePt("/CMS_2017_I1605749/d%02d-x01-y01" % i, "8000", "900" )
def CMS_2012_I1111014_name(i,j) :
if(i+j<100) :
return "/CMS_2012_I1111014/d%02d-x01-y01" % (i+j)
else :
return "/CMS_2012_I1111014/d%03d-x01-y01" % (i+j)
logging.info("Processing CMS_2012_I1111014")
for j in [0,22,44,66,87,106]:
for i in [1,2,3] :
useOnePt(CMS_2012_I1111014_name(i,j), "7000", "20" )
for i in [4,5,6,7]:
useOnePt(CMS_2012_I1111014_name(i,j), "7000", "40" )
for i in [8,9,10]:
useOnePt(CMS_2012_I1111014_name(i,j), "7000", "80" )
for i in [11,12,13,14,15,16]:
useOnePt(CMS_2012_I1111014_name(i,j), "7000", "110" )
for i in [17,18]:
useOnePt(CMS_2012_I1111014_name(i,j), "7000", "210" )
useOnePt(CMS_2012_I1111014_name(19,j), "7000", "260" )
if(j<87) :
for i in [20,21]:
useOnePt(CMS_2012_I1111014_name(i,j), "7000", "400" )
if(j<66) :
useOnePt(CMS_2012_I1111014_name(22,j), "7000", "600" )
for i in [126,127,128] :
for j in [1,2] :
mergeByPt("/CMS_2012_I1111014/d%03d-x01-y%02d" % (i,j), "7000")
logging.info("Processing CMS_2018_I1682495")
for i in [0,1,2,3] :
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 1), "13000", "110" )
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 2), "13000", "260" )
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 3), "13000", "260" )
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 4), "13000", "400" )
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 5), "13000", "400" )
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 6), "13000", "600" )
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 7), "13000", "600" )
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 8), "13000", "900" )
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+ 9), "13000", "900" )
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+10), "13000", "900" )
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+11), "13000", "900" )
useOnePt("/CMS_2018_I1682495/d%02d-x01-y01" % (12*i+12), "13000", "900" )
logging.info("Processing CMS_2015_I1385107")
for i in range(1,9) :
mergeByPt("/CMS_2015_I1385107/d%02d-x01-y01" % i, "2760")
logging.info("Processing CMS_2018_I1663452")
useOneMass("/CMS_2018_I1663452/d01-x01-y01", "13000", "5900" )
useOneMass("/CMS_2018_I1663452/d02-x01-y01", "13000", "4900" )
useOneMass("/CMS_2018_I1663452/d03-x01-y01", "13000", "3900" )
useOneMass("/CMS_2018_I1663452/d04-x01-y01", "13000", "3900" )
useOneMass("/CMS_2018_I1663452/d05-x01-y01", "13000", "2800" )
useOneMass("/CMS_2018_I1663452/d06-x01-y01", "13000", "2800" )
useOneMass("/CMS_2018_I1663452/d07-x01-y01", "13000", "2200" )
logging.info("Processing CMS_2017_I1519995")
useOneMass("/CMS_2017_I1519995/d01-x01-y01", "13000", "3900" )
useOneMass("/CMS_2017_I1519995/d02-x01-y01", "13000", "3900" )
useOneMass("/CMS_2017_I1519995/d03-x01-y01", "13000", "2800" )
useOneMass("/CMS_2017_I1519995/d04-x01-y01", "13000", "2800" )
useOneMass("/CMS_2017_I1519995/d05-x01-y01", "13000", "2200" )
useOneMass("/CMS_2017_I1519995/d06-x01-y01", "13000", "1600" )
logging.info("Processing CMS_2016_I1486238")
for i in [1,5,9,10,12,13,14,16,17] :
useOnePt("/CMS_2016_I1486238/d%02d-x01-y01" % i, "7000", "20" )
mergeByPt("/CMS_2016_I1486238/d11-x01-y01", "7000")
mergeByPt("/CMS_2016_I1486238/d15-x01-y01", "7000")
logging.info("Processing ATLAS_2018_I1634970")
for i in range(1,7) :
mergeByPt("/ATLAS_2018_I1634970/d%02d-x01-y01"%i, "13000")
for i in range(7,13) :
mergeByMass("/ATLAS_2018_I1634970/d%02d-x01-y01"%i, "13000", 1.)
logging.info("Processing ATLAS_2017_I1604271")
for i in range(1,13) :
mergeByPt("/ATLAS_2017_I1604271/d%02d-x01-y01" % i, "8000")
logging.info("Processing CMS_2017_I1598460")
for i in range(1,7) :
mergeByPt("/CMS_2017_I1598460/d%02d-x01-y01" % i, "8000")
logging.info("Processing ATLAS_2019_I1724098")
for i in range(1,45) :
if(i<=6 or (i>=23 and i<=28)) :
useOnePt("/ATLAS_2019_I1724098/d%02d-x01-y01" % i, "13000", "400")
else :
useOnePt("/ATLAS_2019_I1724098/d%02d-x01-y01" % i, "13000", "0")
logging.info("Processing CMS_2018_I1643640")
for i in range(0,5) :
if i == 0 : ioff = 0
else : ioff = 8*i+1
useOnePt("/CMS_2018_I1643640/d%02d-x01-y01"%(ioff+1), "13000", "110")
useOnePt("/CMS_2018_I1643640/d%02d-x01-y01"%(ioff+2), "13000", "260")
useOnePt("/CMS_2018_I1643640/d%02d-x01-y01"%(ioff+3), "13000", "400")
useOnePt("/CMS_2018_I1643640/d%02d-x01-y01"%(ioff+4), "13000", "400")
useOnePt("/CMS_2018_I1643640/d%02d-x01-y01"%(ioff+5), "13000", "600")
useOnePt("/CMS_2018_I1643640/d%02d-x01-y01"%(ioff+6), "13000", "600")
useOnePt("/CMS_2018_I1643640/d%02d-x01-y01"%(ioff+7), "13000", "600")
useOnePt("/CMS_2018_I1643640/d%02d-x01-y01"%(ioff+8), "13000", "900")
if(i==0) :
useOnePt("/CMS_2018_I1643640/d%02d-x01-y01"%(ioff+9), "13000", "900")
logging.info("Processing CMS_2019_I1719955")
for i in range(0,2) :
useOnePt("/CMS_2019_I1719955/d%02d-x01-y01"%(9*i+1), "13000", "110")
useOnePt("/CMS_2019_I1719955/d%02d-x01-y01"%(9*i+2), "13000", "260")
useOnePt("/CMS_2019_I1719955/d%02d-x01-y01"%(9*i+3), "13000", "400")
useOnePt("/CMS_2019_I1719955/d%02d-x01-y01"%(9*i+4), "13000", "400")
useOnePt("/CMS_2019_I1719955/d%02d-x01-y01"%(9*i+5), "13000", "600")
useOnePt("/CMS_2019_I1719955/d%02d-x01-y01"%(9*i+6), "13000", "600")
useOnePt("/CMS_2019_I1719955/d%02d-x01-y01"%(9*i+7), "13000", "600")
useOnePt("/CMS_2019_I1719955/d%02d-x01-y01"%(9*i+8), "13000", "900")
useOnePt("/CMS_2019_I1719955/d%02d-x01-y01"%(9*i+9), "13000", "900")
logging.info("Processing ATLAS_2020_I1808726")
pts=["400","600","900"]
for i in range (0,3) :
useOnePt("/ATLAS_2020_I1808726/d%02d-x01-y01"%(73+i),"13000",pts[i])
for j in range (0,6) :
for k in range(1,5) :
useOnePt("/ATLAS_2020_I1808726/d%02d-x01-y01"%(4*i+12*j+k),"13000",pts[i])
logging.info("Processing ATLAS_2019_I1740909")
for i in [1,2,9]:
mergeByPt("/ATLAS_2019_I1740909/d%02d-x01-y01" % i, "13000")
pts = ["80" ,"110","260","400","400",
"600","600","600","900","900",
"900","900","900","1900"]
for i in [13,27,41,55,69,83,97,111,125,139,153,167] :
for j in range(0,14) :
ihist=i+j
if ihist < 100:
useOnePt("/ATLAS_2019_I1740909/d%02d-x01-y01" % ihist, "13000",pts[j])
else :
useOnePt("/ATLAS_2019_I1740909/d%03d-x01-y01" % ihist, "13000",pts[j])
logging.info("Processing ATLAS_2021_I1913061")
for i in range(1,5) :
useOnePt("/ATLAS_2021_I1913061/d%02d-x01-y01" % ihist, "13000","40")
for i in range(5,7) :
useOnePt("/ATLAS_2021_I1913061/d%02d-x01-y01" % ihist, "13000","40")
for i in range(7,9) :
mergeByPt("/ATLAS_2021_I1913061/d%02d-x01-y01" % i, "13000")
# rescaling for semi-leptonic top decays (we only simulate 1 charge combination)
for i in range(96,116,2) :
rescale("/ATLAS_2018_I1656578/d%s-x01-y01" % i,2.)
for i in range(15,29,2) :
rescale("/ATLAS_2017_I1614149/d%s-x01-y01" % i,2.)
for i in range(1,23,2) :
rescale("/ATLAS_2015_I1404878/d%02d-x01-y01" % i,2.)
rescale("/ATLAS_2015_I1397637/d01-x01-y01",2.)
for i in range(1,22,1) :
rescale("/ATLAS_2015_I1345452/d%02d-x01-y01" % i,2.)
for i in range(1,10,1) :
rescale("/ATLAS_2014_I1304688/d%02d-x01-y01" % i,2.)
for i in range(1,82) :
rescale("/CMS_2018_I1663958/d%02d-x01-y01" % i,2.)
for i in range(169,173,1) :
rescale("/CMS_2018_I1663958/d%02d-x01-y01" % i,2.)
for i in range(8,15) :
rescale("/CMS_2018_I1662081/d%02d-x01-y01" % i,2.)
for i in range(1,41) :
rescale("/CMS_2016_I1491950/d%02d-x02-y01" % i,2.)
for i in range(1,13) :
rescale("/CMS_2016_I1454211/d%02d-x01-y01" % i,2.)
rescale("/CMS_2017_I1518399/d01-x01-y01",2.)
for i in [4,8,12,16,20,24,28,32,36,40,44,48,52,75,76,77,78,79] :
rescale("/ATLAS_2019_I1750330/d%02d-x01-y01" % i,2.)
for i in [115,116,117,118,119,155,156,157,158,159,189,190,191,192,212,213,214,235,236,237,238,263,264,265,266,291,292,293,294,319,320,321,322,347,348,349,350,375,376,377,378,403,404,405,406,426,427,428,449,450,451,452,477,478,479,480,505,506,507,508,843,847,851,855,859,863,867,871,875,879,883,887,899,900,901,913,914,923,924,933,934,943,944,957,958,959,975,976,977,993,994,995,1007,1008,1021,1022,1023,] :
rescale("/ATLAS_2019_I1750330/d%s-x01-y01" % i,2.)
# Choose output file
name = args[0]+"-Jets.yoda"
yoda.writeYODA(outhistos,name)
sys.exit(0)
diff --git a/Tests/python/mergeLowEnergy.py.in b/Tests/python/mergeLowEnergy.py.in
--- a/Tests/python/mergeLowEnergy.py.in
+++ b/Tests/python/mergeLowEnergy.py.in
@@ -1,131 +1,135 @@
#! @PYTHON@
from __future__ import print_function
import yoda,glob,math,optparse
import subprocess,os
op = optparse.OptionParser(usage=__doc__)
op.add_option("-m" , dest="plots" , default=[], action="append")
opts, args = op.parse_args()
if(len(args)!=1) :
print ('Must be one and only 1 name')
quit()
name=args[0].split("-")
cmd3_weights = { 2007. : [0.5 ,4259], 1980 : [1 , 2368], 1951 : [11,5230],
1907.5: [17.5,5497], 1877 : [7 ,16803], 1830 : [30,8287],
1740. : [40 ,8728], 1640 : [40, 7299] }
wSum=0.
for key in cmd3_weights.keys() :
wSum+= cmd3_weights[key][1]
for key in cmd3_weights.keys() :
cmd3_weights[key][1] /= wSum
-
-for runType in ["NonPerturbative","Perturbative"]:
+output=""
+labels={ "NonPerturbative" : "Non-Pert" ,
+ "Perturbative" : "Pert" ,
+ "Resonance" : "Res" }
+for runType in ["NonPerturbative","Perturbative","Resonance"]:
outhistos={}
for fileName in glob.glob("Rivet-LowEnergy-%s-%s-*.yoda" % (name[0],runType) ):
energy = float(fileName.split("-")[-1].strip(".yoda"))
energyMeV = energy*1000.
aos = yoda.read(fileName)
for hpath,histo in aos.items():
if("/_" in hpath or "TMP" in hpath or "RAW" in hpath) : continue
if(len(opts.plots)>0 and hpath not in opts.plots) : continue
if(type(histo)==yoda.core.Histo1D or
(type(histo)==yoda.core.Scatter2D and hpath=="/BESIII_2019_I1726357/d03-x01-y01") ) :
if( "CMD3_2019_I1770428" in hpath ) :
val=0.
for key in cmd3_weights.keys() :
if(abs(energyMeV-val)>abs(energyMeV-key)) :
val=key
histo.scaleW(cmd3_weights[val][1])
if(hpath in outhistos) :
outhistos[hpath] += histo
else :
outhistos[hpath] = histo
else :
outhistos[hpath] = histo
continue
# create histo if it doesn't exist
elif(hpath not in outhistos) :
title=""
path=""
if hasattr(histo, 'title'):
title=histo.title()
if hasattr(histo, 'path'):
path=histo.path()
outhistos[hpath] = yoda.core.Scatter2D(path,title)
matched = False
for i in range(0,aos[hpath].numPoints()) :
x = aos[hpath].points()[i].x()
delta=1e-5
if("KLOE_2009_I797438" in hpath or "KLOE_2005_I655225" in hpath or
"KLOE2_2017_I1634981" in hpath or "FENICE_1994_I377833" in hpath or
"FENICE_1996_I426675" in hpath):
x=math.sqrt(x)
delta=1e-3
if(abs(x-energy)<1e-3*delta or abs(x-energyMeV)<delta) :
duplicate = False
for j in range(0,outhistos[hpath].numPoints()) :
if(outhistos[hpath].points()[j].x()==aos[hpath].points()[i].x()) :
duplicate = True
break
if(not duplicate) :
outhistos[hpath].addPoint(aos[hpath].points()[i])
matched = True
break
if(matched) : continue
for i in range(0,aos[hpath].numPoints()) :
xmin = aos[hpath].points()[i].xMin()
xmax = aos[hpath].points()[i].xMax()
if("KLOE_2009_I797438" in hpath or "KLOE_2005_I655225" in hpath or
"KLOE2_2017_I1634981" in hpath or "FENICE_1994_I377833" in hpath or
"FENICE_1996_I426675" in hpath) :
xmin=math.sqrt(xmin)
xmax=math.sqrt(xmax)
if((energy > xmin and energy < xmax) or
(energyMeV > xmin and energyMeV < xmax) ) :
duplicate = False
for j in range(0,outhistos[hpath].numPoints()) :
if(outhistos[hpath].points()[j].x()==aos[hpath].points()[i].x()) :
duplicate = True
break
if(not duplicate) :
outhistos[hpath].addPoint(aos[hpath].points()[i])
break
if len(outhistos) == 0: continue
p = subprocess.Popen(["rivet-config", "--datadir"],stdout=subprocess.PIPE)
path=p.communicate()[0]
if not isinstance(path, bytes) :
path = path.encode("UTF-8").strip()
else :
path=path.strip().decode('utf-8')
temp = list(outhistos.keys())
for val in temp :
if type(outhistos[val]) is yoda.core.Scatter2D :
if(outhistos[val].numPoints()==0) :
del outhistos[val]
continue
analysis = val.split("/")[1]
aos=yoda.read(os.path.join(os.path.join(os.getcwd(),path),analysis+".yoda"))
ref = aos["/REF"+val]
for point in ref.points() :
matched=False
for point2 in outhistos[val].points() :
if(point2.x()==point.x()) :
matched=True
break
if(matched) : continue
outhistos[val].addPoint(point.x(),0,point.xErrs(),(0.,0.))
elif (type(outhistos[val]) is yoda.core.Histo1D or
type(outhistos[val]) is yoda.core.Profile1D) :
if(outhistos[val].numBins()==0) :
del outhistos[val]
continue
else :
print (type(outhistos[val]) )
yoda.writeYODA(outhistos,"LowEnergy-%s-%s.yoda" % (runType,args[0]))
-
+ output+="LowEnergy-%s-%s.yoda:%s " % (runType,args[0],labels[runType])
+print(output)
diff --git a/Tests/python/plot-EE.in b/Tests/python/plot-EE.in
--- a/Tests/python/plot-EE.in
+++ b/Tests/python/plot-EE.in
@@ -1,4637 +1,6050 @@
#! @PYTHON@
+# -*- mode: python -*-
from __future__ import print_function
import glob,os,sys
if __name__ == "__main__":
import logging
from optparse import OptionParser, OptionGroup
parser = OptionParser(usage="%prog name")
verbgroup = OptionGroup(parser, "Verbosity control")
verbgroup.add_option("-v", "--verbose", action="store_const", const=logging.DEBUG, dest="LOGLEVEL",
default=logging.INFO, help="print debug (very verbose) messages")
verbgroup.add_option("-q", "--quiet", action="store_const", const=logging.WARNING, dest="LOGLEVEL",
default=logging.INFO, help="be very quiet")
parser.add_option_group(verbgroup)
parser.add_option("--with-gg",
action='store_true' ,
dest="gg",
default=False,
help="Include gg analyese")
parser.add_option("--without-gg",
action='store_false',
dest="gg",
default=False,
help="Don\'t include gg analyses")
(opts, args) = parser.parse_args()
logging.basicConfig(level=opts.LOGLEVEL, format="%(message)s")
## Check args
if len(args) < 1:
logging.error("Must specify at least the name of the files")
sys.exit(1)
directory=args[0]
header="""<html>
<head>
<title>{title}</title>
<style>
html {{ font-family: sans-serif; }}
img {{ border: 0; }}
a {{ text-decoration: none; font-weight: bold; }}
</style>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({{
tex2jax: {{inlineMath: [["$","$"]]}}
}});
</script>
<script type="text/javascript"
src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
</head>
<body><center><h1>{title}</h1></center>"""
analyses={ "HadronDecays" : { },
+ "WDecays" : { "Mult" : {},
+ "Spectrum" : {},},
"TauDecays" : { "1pi" : {},
"2pi" : {},
"Kpi" : {},
"KK" : {},
"lnu" : {},
"Keta" : {},
"3pi" : {},
"Kpipi" : {},
"KKpi" : {},
"2pieta" : {},
"2pigamma" : {},
"3K" : {},
"4pi" : {},
"5pi" : {},
"6pi" : {},},
"Charged" : {"TotalChargedMult" : { 0 : {}, 1 : {}, 4 : {}, 5 : {}, 51 : {}, 41 : {} , "C" : {} },
"ChargedSpectrum" : { 0 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}},
1 : { "x" : {}, "p" : {}, "xi" : {}},
2 : { "x" : {}, "p" : {}, "xi" : {}},
4 : { "x" : {}, "p" : {}, "xi" : {}},
5 : { "x" : {}, "p" : {}, "xi" : {}},
21 : { "x" : {}, "p" : {}, "xi" : {}},
"C" : { "x" : {}, "p" : {}, "xi" : {}}},
"ChargedRapidityThrust" : { },
"ChargedpTInThrust" : { },
"ChargedpTOutThrust" : { },
"ChargedpTThrust" : { },
"ChargedpTvsxpThrust" : { },
"ChargedpTOutvsxpThrust" : { },
+ "ChargedMultvsThrust" : { },
"ChargedxFThrust" : { },
"ChargedRapiditySphericity" : { },
"ChargedpTInSphericity" : { },
"ChargedpTOutSphericity" : { },
"ChargedpLSphericity" : { },
"ChargedpTSphericity" : { },
"ChargedpT2Sphericity" : { },
"ChargedFlowSphericity" : { },
"ChargedEnergyFlowSphericity" : { },
"ChargedAveragepT2inSphericity" : { },
"ChargedAveragepT2outSphericity" : { },
"ChargedAveragepTThrust" : { },
"ChargedAveragepT2Thrust" : { },
"ChargedSumpTThrust" : { },
"ChargedSumpT2Thrust" : { },
"ChargedAveragepTSphericity" : { },
"ChargedAveragepT2Sphericity" : { },
"ChargedSumpTSphericity" : { },
"ChargedSumpT2Sphericity" : { },
+ "ChargedAveragepTInThrust" : { },
+ "ChargedAveragepTOutThrust" : { },
+ "ChargedAverageyThrust" : { },
+ "ChargedAveragexThrust" : { },
"DistChargedMult" : {0 : {}, 1 : {}, 2 : {}, 4 : {}, 5 : {} , 21 : {}, "C" :{}}},
"IdentifiedParticle" : { 22 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
111 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
211 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
221 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
331 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
223 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
333 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
321 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
311 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
313 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
323 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
+ 315 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
2212 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
413 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
423 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
10413 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
10423 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
3122 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
3212 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
2224 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
3312 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
3222 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
"3224B" : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
431 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
433 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
435 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
10433 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
20433 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
10431 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
3112 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
3224 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
3114 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
3324 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
3124 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
443 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
100443 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
9010221 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
9000211 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
225 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
335 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
113 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
213 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
+ 20223 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
+ 20333 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
421 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
411 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
415 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
425 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
511 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
513 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4122 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
3334 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4332 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4132 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4232 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4112 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4222 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4114 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4124 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4224 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4312 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4322 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4314 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
4324 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
14122 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
+ 1000010020 : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}},
"321/2212" : { "x" : {}, "p" : {}, "xi" : {}, "Other" : {}, "Ratio" : {}}},
"IdentifiedParticleFlavour" : {111 : { 1 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
4 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
5 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
41 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
51 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} } },
211 : { 1 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
4 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
5 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
41 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
51 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} } },
321 : { 1 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
4 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
5 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
41 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
51 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} } },
311 : { 1 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
4 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
5 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
41 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
51 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} } },
313 : { 1 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
4 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
5 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
41 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
51 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} } },
333 : { 1 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
4 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
5 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
41 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
51 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} } },
2212 : { 1 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
4 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
5 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
41 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
51 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} } },
3122 : { 1 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
4 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
5 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
41 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
51 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} } },
413 : { 1 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
4 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
5 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
41 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
51 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} } },
"321/2212" : { 1 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
4 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
5 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
41 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} },
51 : {"x" : {}, "xi" : {}, "p" : {}, "Ratio" : {}, "Other" : {} } },},
"MultiplicityFlavour" : {111 : { 1 : {}, 4 : {}, 5 : {}, 41 : {}, 51 : {} },
211 : { 1 : {}, 4 : {}, 5 : {}, 41 : {}, 51 : {} },
321 : { 1 : {}, 4 : {}, 5 : {}, 41 : {}, 51 : {} },
2212 : { 1 : {}, 4 : {}, 5 : {}, 41 : {}, 51 : {} },
413 : { 1 : {}, 4 : {}, 5 : {}, 41 : {}, 51 : {} },
3122 : { 1 : {}, 4 : {}, 5 : {}, 41 : {}, 51 : {} },
313 : { 1 : {}, 4 : {}, 5 : {}, 41 : {}, 51 : {} },
333 : { 1 : {}, 4 : {}, 5 : {}, 41 : {}, 51 : {} },
311 : { 1 : {}, 4 : {}, 5 : {}, 41 : {}, 51 : {} },
"321/2212" : { 1 : {}, 4 : {}, 5 : {}, 41 : {}, 51 : {} },
},
"Multiplicity" : { 22: {}, 111 : {}, 211 : {}, 221 : {}, 331 : {}, 113 : {},9010221 : {},9000211 : {}, 213 : {},
223 : {}, 333 : {}, 321 : {}, 311 : {}, 411 : {}, 421 : {}, 431 : {}, 10431 : {}, 521 : {}, "511B" : {}, 531 : {}, 511 : {},
313 : {}, 323 : {}, 2212 : {}, 413 : {}, 423 : {}, 425 : {}, 10423 : {}, 433 : {}, 10413 : {}, 415 : {}, 10433 : {}, 513 : {}, 515 : {},
3122 : {}, 3312 : {}, 3212 : {}, 3112 : {}, 3114 : {}, 3324: {}, 3334 : {}, "321/2212" : {}, 4132 : {}, 4232 : {}, 4124 : {}, 14122 : {},
4212 : {}, 4214 : {},
443 : {}, 100443 : {}, 553 : {}, 20223 : {}, 20333 : {}, 20443 : {}, 225 :{}, 335 : {}, 20433 : {}, 435 : {}, 315 : {}, 325 : {},
3222 : {}, 2224 : {}, 3224 : {}, 3114 : {}, 4122 : {}, 5122 :{}, 3124 :{}, 4222 : {}, "3222B" : {}, "3224B" : {}, 4332 : {}, 4334 : {},
- 4324 : {}, 4224 : {}, 4314 : {}
+ 4324 : {}, 4224 : {}, 4314 : {},1000010020 : {},
},
"EventShapes" : { "T" : {}, "S" : {}, "D" : {}, "O" : {}, "Minor" : {}, "Major" : {},
"y12_dur" : {}, "y23_dur" : {}, "y34_dur" : {}, "y45_dur" : {}, "y56_dur" : {},
"y12_jade" : {}, "y23_jade" : {}, "y34_jade" : {}, "y45_jade" : {}, "y56_jade" : {},
+ "y12_cam" : {}, "y23_cam" : {}, "y34_cam" : {}, "y45_cam" : {}, "y56_cam" : {},
"HeavyJetMass" : {} , "JetMassDifference" : {} ,
- "LightJetMass" : {}, "TotalJetMass" : {} , "EEC" : {}, "AEEC" : {} ,
+ "LightJetMass" : {}, "TotalJetMass" : {} , "EEC" : {}, "AEEC" : {} , "JCEF" : {},
"P" : {}, "A" : {} , "Qx" : {}, "Q21" : {}, "BW" : {}, "BT" : {}, "BN" : {},
"Bdiff" : {}, "C" : {},
"1jet_dur" : {}, "2jet_dur" : {}, "3jet_dur" : {}, "4jet_dur" : {}, "5jet_dur" : {}, "6jet_dur" : {},
"1jet_jade" : {}, "2jet_jade" : {}, "3jet_jade" : {}, "4jet_jade" : {}, "5jet_jade" : {}, "6jet_jade" : {},
+ "1jet_cam" : {}, "2jet_cam" : {}, "3jet_cam" : {}, "4jet_cam" : {}, "5jet_cam" : {}, "6jet_cam" : {},
"Moment_T":{}, "Moment_H":{},"Moment_C":{},"Moment_S":{},"Moment_L":{},"Moment_y":{},"Moment_BW":{},
"Moment_BN":{},"Moment_BT":{},"Moment_O":{},"Moment_M":{},"Moment_m":{},},
"FourJet" : {"BZ" : {}, "KSW" : {}, "NR" : {}, "alpha34" : {} },
"EventShapesFlavour" : { "T" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},
"S" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},
"D" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},
"O" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},
"Minor" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},
"Major" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},
"y12" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},"y23" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},"y34" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},"y45" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},"y56" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}}, "HeavyJetMass" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}} , "JetMassDifference" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}} ,
"LightJetMass" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}}, "TotalJetMass" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}} , "EEC" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}}, "AEEC" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}} ,
"P" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}}, "A" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}} , "BW" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}}, "BT" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}}, "BN" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},
"Bdiff" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}}, "C" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},
"1jet" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},"2jet" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},"3jet" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},"4jet" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},"5jet" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},"6jet" : { 1 : {}, 2 : {}, 4 : {}, 5 : {}},},
"QED" : {},
"Polarization" : { 213 : { "alpha" : {}, "rho00" : {}, "cos" : {}, "rho10" : {}, "rho11" : {}, "phi" : {}, "Other" : {}},
223 : { "alpha" : {}, "rho00" : {}, "cos" : {}, "rho10" : {}, "rho11" : {}, "phi" : {}, "Other" : {}},
413 : { "alpha" : {}, "rho00" : {}, "cos" : {}, "rho10" : {}, "rho11" : {}, "phi" : {}, "Other" : {}},
513 : { "alpha" : {}, "rho00" : {}, "cos" : {}, "rho10" : {}, "rho11" : {}, "phi" : {}, "Other" : {}},
3122 : { "alpha" : {}, "rho00" : {}, "cos" : {}, "rho10" : {}, "rho11" : {}, "phi" : {}, "Other" : {}},
333 : { "alpha" : {}, "rho00" : {}, "cos" : {}, "rho10" : {}, "rho11" : {}, "phi" : {}, "Other" : {}},
313 : { "alpha" : {}, "rho00" : {}, "cos" : {}, "rho10" : {}, "rho11" : {}, "phi" : {}, "Other" : {}},
5122 : { "alpha" : {}, "rho00" : {}, "cos" : {}, "rho10" : {}, "rho11" : {}, "phi" : {}, "Other" : {}},
}
}
particleNames = {
11 : "$e^-$", 13 : "$\\mu^-$",
22 : "$\\gamma$",
111 : "$\\pi^0$", 211 : "$\\pi^\\pm$", 221 : "$\\eta$", 331 : "$\\eta^\\prime$",
113 : "$\\rho^0$", 213 : "$\\rho^\\pm$", 223 : "$\\omega$", 333 : "$\\phi$",
115 : "$a_2^0$", 215 : "$a_2^\pm$", 225 : "$f_2$", 335 : "$f^\\prime_2$",
20223 : "$f_1$", 20333 : "$f^\\prime_1$", 20113 : "$a^0_1$", 20213 : "$a^\\pm_1$",
9010221 : "$f_0(980)$", 9000211 : "$a^\\pm_0(980)$",
311 : "$K^0,\\bar{K}^0$", 321 : "$K^\\pm$", 313 : "$K^{*0},\\bar{K}^{*0}$", 323 : "$K^{*\\pm}$",
315 : "$K^0_2,\\bar{K}^0_2$", 325 : "$K^\\pm_2$",
411 : "$D^\\pm$", 421 : "$D^0,\\bar{D}^0$", 413: "$D^{*\\pm}$", 415 : "$D^\\pm_2$", 425 : "$D^0_2, \\bar{D}^0_2$", 423: "$D^{*0},\\bar{D}^{*0}$", 100421 : "$D^0(2550),\\bar{D}^0(2550)$",
100423 : "$D^*_1(2600)^0,\\bar{D}^*_1(2600)$", 427 : "$D^*_3(2750)^0,\\bar{D}^*_3(2750)$", 20425 : "$D_2(2740)^0,\\bar{D}_2(2740)$",
10423: "$D^0_1,\\bar{D}_1^0$",10413: "$D^\\pm_1$",
431 : "$D_s^\\pm$", 435 : "$D^\\pm_{s2}$", 20433 : "$D_{s1}(2460)^\\pm$", 433 : "$D_s^{*\\pm}$", 10433 : "$D_{s1}(2536)^\pm$", 10431 : "$D_{s0}(2319)^\pm$",
100433 : "$D^*_{s1}(2700)^\pm$", 30433 : "$D^*_{s1}(2860)^\pm$",437 : "$D^*_{s3}(2860)^\pm$",
511 : "$B^0,\\bar{B}^0$", "511B" : "$B^0,\\bar{B}^0, B^\\pm$",
521 : "$B^\\pm$", 531 : "$B^0_s,\\bar{B}^0_s$", 513 : "$B^*$",515 : "$B^{**}$",
- 443 : "$J/\\psi$" , 100443 : "$\\psi(2S)$", 553 : "$\\Upsilon(1S)$", 20443 : "$\\chi_{c1}(1P)$",
- 441 : "$\\eta_c$", 100553 : "$\\Upsilon(2S)$", 200553 : "$\\Upsilon(3S)$", 300553 : "$\\Upsilon(4S)$", 9000553 : "$\\Upsilon(5S)$", 445 : "$\\chi_{c2}(1P)$",
+ 443 : "$J/\\psi$" , 100443 : "$\\psi(2S)$", 30443 : "$\\psi(3770)$", 441 : "$\\eta_c$", 445 : "$\\chi_{c2}(1P)$", 10441 : "$\chi_{c0}(1P)$",
+ 553 : "$\\Upsilon(1S)$", 20443 : "$\\chi_{c1}(1P)$",100553 : "$\\Upsilon(2S)$", 200553 : "$\\Upsilon(3S)$", 300553 : "$\\Upsilon(4S)$", 9000553 : "$\\Upsilon(5S)$",
120553 : "$\chi_{b1}(2S)$", 110551 : "$\chi_{b0}(2S)$", 100555 : "$\chi_{b2}(2S)$",
- 30443 : "$\\psi(3770)$",
+ 543 : "$B_c^+$",
+
2212 : "$p,\\bar{p}$", 2224 : "$\\Delta^{++},\\bar{\\Delta}^{--}$",
-
3122 : "$\\Lambda^0,\\bar{\\Lambda}^0$",
3222 : "$\\Sigma^+,\\bar{\Sigma}^-$", "3222B" : "$\\Sigma^\\pm,\\bar{\Sigma}^\\pm$",
3212 : "$\\Sigma^0,\\bar{\Sigma}^0$", 3112 : "$\\Sigma^-,\\bar{\Sigma}^+$",
3224 : "$\\Sigma^{*+},\\bar{\Sigma}^{*-}$", "3224B" : "$\\Sigma^{*\\pm},\\bar{\Sigma}^{*\\pm}$",
3214 : "$\\Sigma^{*0},\\bar{\Sigma}^{*0}$", 3114 : "$\\Sigma^{*-},\\bar{\Sigma}^{*+}$",
3322 : "$\\Xi^0,\\bar{\\Xi}^0$", 3312 : "$\\Xi^-,\\bar{\\Xi}^+$", 3324 : "$\\Xi^{*0},\\bar{\\Xi}^{*0}$", 3314 : "$\\Xi^{*-},\\bar{\\Xi}^{*+}$",
3334 : "$\\Omega^-,\\bar{\\Omega}^+$", 3124 : "$\\Lambda^0(1520),\\bar{\\Lambda}^0(1520)$",
4122 : "$\\Lambda_c^+,\\bar{\\Lambda}^+_c$", 4222 : "$\\Sigma_c^{++}, \\Sigma_c^{0}, \\bar{\\Sigma}_c^{++}, \\bar{\\Sigma}_c^{0}$",
4224 : "$\\Sigma_c^{*++}, \\Sigma_c^{*0}, \\bar{\\Sigma}_c^{*++}, \\bar{\\Sigma}_c^{*0}$",
14122 : "$\\Lambda_c(2595)^+,\\bar{\\Lambda}(2595)_c^+$", 4314 : "$\\Xi^{*0}_c$", 4324 : "$\\Xi^{*+}_c$", 4322 : "$\\Xi_c^{\\prime+}$",
4212 : "$\\Sigma_c^0$", 4214 : "$\\Sigma_c^{*0}$",
4312 : "$\\Xi_c^{\\prime0}$",
- 5122 : "$\\Lambda_b^0,\\bar{\\Lambda}^0_b$",
4124 : "$\\Lambda_c(2625)^+,\\bar{\\Lambda}(2625)_c^+$", 4112 : "$\\Sigma_c^0,\\bar{\\Sigma}_c^0$", 4114 : "$\\Sigma_c^{*0},\\bar{\\Sigma}_c^{*0}$",
4332 : "$\\Omega_c^0,\\bar{\\Omega}_c^0$", 4334 : "$\\Omega_c^{*0},\\bar{\\Omega}_{c}^{*0}$", 4132 : "$\\Xi_c^0,\\bar{\\Xi}_c^0$", 4232 : "$\\Xi_c^+,\\bar{\\Xi}_c^-$",
- "321/2212" : "$K^\\pm,p,\\bar{p}$"
+ 5122 : "$\\Lambda_b^0,\\bar{\\Lambda}^0_b$", 101254 : "$\\Lambda_b(5920)^0$",
+ "321/2212" : "$K^\\pm,p,\\bar{p}$",
+
+ 1000010020 :"deuteron"
}
# hadron species
mLight = [211,111,221,331,213,113,223,333,225,335,20213,20113,20223,20333,9010221, 9000111, 9000211]
mStrange = [311,321,313,323,315,325]
mCharm = [411,421,413,423,415,425,10413,10423,20425,427,100421,100423,431,433,435,10431,10433,20433,30433,437,100433]
mBottom = [511,"511B",521,531,513,515]
-mccbar = [441,443,100443,20443,30443]
-mbbbar = [553,100553,200553,300553,9000553,110551,120553,100555]
-bLight = [2212,2224]
+mccbar = [441,443,100443,10441,20443,30443,445]
+mbbbar = [553,100553,200553,300553,400553,9000553,110551,120553,100555]
+mbc = [543]
+bLight = [2212,2224,1000010020]
bStrange = [3122,3222,"3222B",3212,3112,3114,3224,"3224B",3312,3322,3324,3334,3124]
bCharm = [4122,4112,4212,4222,4214,4114,4332,4132,4232,4312,4322,14122,4124,4224,4314,4324,4334]
-bBottom = [5122]
+bBottom = [5122,101254]
# hadron decays
modes = {}
# neutral pion
analyses["HadronDecays"][111] = { "Modes" : {"$\\pi^0\\to\\gamma e^+e^-$" : {} } }
analyses["HadronDecays"][111]["Modes"]["$\\pi^0\\to\\gamma e^+e^-$"]["MC"] = ["/MC_Meson_Meson_Leptons_Decay/h2_111p_22p_11_mVf",
"/MC_Meson_Meson_Leptons_Decay/h2_111p_22p_11_mVfbar",
"/MC_Meson_Meson_Leptons_Decay/h2_111p_22p_11_mff"]
analyses["HadronDecays"][111]["Modes"]["$\\pi^0\\to\\gamma e^+e^-$"]["data"]=["/A2_2017_I1498079/d01-x01-y01"]
# eta
analyses["HadronDecays"][221] = { "Modes" : {"$\\eta\\to\\pi^0\\pi^0\\pi^0$" : {},
"$\\eta\\to\\pi^+\\pi^-\\pi^0$" : {},
"$\\eta\\to\\gamma e^+e^-$" : {},
"$\\eta\\to\\gamma \\mu^+\\mu^-$" : {},
"$\\eta\\to\\gamma \\pi^+\\pi^-$" : {},
"$\\eta\\to\\gamma\\gamma\\pi^0$" : {} } }
+analyses["HadronDecays"][221]["Modes"]["$\\eta\\to\\pi^0\\pi^0\\pi^0$"]["data"] = ["/BESIII_2015_I1376484/d02-x01-y01"]
analyses["HadronDecays"][221]["Modes"]["$\\eta\\to\\pi^0\\pi^0\\pi^0$"]["MC" ] = ["/MC_Eta_Decay/dpi0pi0_0"]
analyses["HadronDecays"][221]["Modes"]["$\\eta\\to\\pi^+\\pi^-\\pi^0$"]["MC" ] = ["/MC_Eta_Decay/dpi0pim_0","/MC_Eta_Decay/dpi0pip_0",
"/MC_Eta_Decay/dpippim_0"]
analyses["HadronDecays"][221]["Modes"]["$\\eta\\to\\pi^+\\pi^-\\pi^0$"]["data"] = ["/KLOE2_2016_I1416990/d01-x01-y01","/KLOE2_2016_I1416990/d02-x01-y01",
"/KLOE2_2016_I1416990/d02-x01-y02","/KLOE2_2016_I1416990/d02-x01-y03",
"/KLOE2_2016_I1416990/d02-x01-y04","/KLOE2_2016_I1416990/d02-x01-y05",
"/KLOE2_2016_I1416990/d02-x01-y06","/KLOE2_2016_I1416990/d02-x01-y07",
"/KLOE2_2016_I1416990/d02-x01-y08","/KLOE2_2016_I1416990/d02-x01-y09",
"/KLOE2_2016_I1416990/d02-x01-y10","/KLOE2_2016_I1416990/d02-x01-y11",
"/KLOE2_2016_I1416990/d02-x01-y12","/KLOE2_2016_I1416990/d02-x01-y13",
"/KLOE2_2016_I1416990/d02-x01-y14","/KLOE2_2016_I1416990/d02-x01-y15",
- "/KLOE2_2016_I1416990/d02-x01-y16","/KLOE2_2016_I1416990/d02-x01-y17"]
+ "/KLOE2_2016_I1416990/d02-x01-y16","/KLOE2_2016_I1416990/d02-x01-y17",
+ "/BESIII_2015_I1376484/d01-x01-y01","/BESIII_2015_I1376484/d01-x01-y02"]
analyses["HadronDecays"][221]["Modes"]["$\\eta\\to\\gamma e^+e^-$"]["MC" ] = ["/MC_Meson_Meson_Leptons_Decay/h2_221p_22p_11_mVf",
"/MC_Meson_Meson_Leptons_Decay/h2_221p_22p_11_mVfbar",
"/MC_Meson_Meson_Leptons_Decay/h2_221p_22p_11_mff"]
analyses["HadronDecays"][221]["Modes"]["$\\eta\\to\\gamma e^+e^-$"]["data"] = ["/A2_2017_I1486671/d01-x01-y01"]
analyses["HadronDecays"][221]["Modes"]["$\\eta\\to\\gamma \\mu^+\\mu^-$"]["data" ] = ["/NA60_2016_I1452485/d01-x01-y01"]
analyses["HadronDecays"][221]["Modes"]["$\\eta\\to\\gamma \\mu^+\\mu^-$"]["MC" ] = ["/MC_Meson_Meson_Leptons_Decay/h2_221p_22p_13_mVf",
"/MC_Meson_Meson_Leptons_Decay/h2_221p_22p_13_mVfbar",
"/MC_Meson_Meson_Leptons_Decay/h2_221p_22p_13_mff"]
analyses["HadronDecays"][221]["Modes"]["$\\eta\\to\\gamma \\pi^+\\pi^-$"]["MC" ] = ["/MC_Eta_Decay/mpimgamma_0","/MC_Eta_Decay/mpipgamma_0",
"/MC_Eta_Decay/mpippim_0" ,"/MC_Eta_Decay/photonenergy_0"]
analyses["HadronDecays"][221]["Modes"]["$\\eta\\to\\gamma\\gamma\\pi^0$" ]["MC" ] = ["/MC_Eta_Decay/mgammagamma_0","/MC_Eta_Decay/mpi0gamma_0"]
# eta'
analyses["HadronDecays"][331] = { "Modes" : {"$\\eta^\\prime\\to\\pi^0\\pi^0\\pi^0$" : {},
"$\\eta^\\prime\\to\\pi^+\\pi^-\\pi^0$" : {},
"$\\eta^\\prime\\to\\eta\\pi^0\\pi^0$" : {},
"$\\eta^\\prime\\to\\eta\\pi^+\\pi^-$" : {},
"$\\eta^\\prime\\to\\gamma e^+e^-$" : {},
"$\\eta^\\prime\\to\\gamma \\mu^+\\mu^-$" : {},
"$\\eta^\\prime\\to\\gamma \\pi^+\\pi^-$" : {},
+ "$\\eta^\\prime\\to\\pi^+\\pi^-e^+e^-$" : {},
"$\\eta^\\prime\\to\\gamma\\gamma\\pi^0$" : {} } }
analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\gamma e^+e^-$"]["MC" ] = ["/MC_Meson_Meson_Leptons_Decay/h2_331p_22p_11_mVf",
"/MC_Meson_Meson_Leptons_Decay/h2_331p_22p_11_mVfbar",
"/MC_Meson_Meson_Leptons_Decay/h2_331p_22p_11_mff"]
analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\gamma e^+e^-$"]["data"] = ["/BESIII_2015_I1364494/d01-x01-y03"]
analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\gamma \\mu^+\\mu^-$"]["MC"] = ["/MC_Meson_Meson_Leptons_Decay/h2_331p_22p_13_mff",
"/MC_Meson_Meson_Leptons_Decay/h2_331p_22p_13_mVfbar",
"/MC_Meson_Meson_Leptons_Decay/h2_331p_22p_13_mVf"]
-analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\pi^+\\pi^-\\pi^0$"]["MC"] = ["/MC_Eta_Decay/dpi0pim_1","/MC_Eta_Decay/dpippim_1",
- "/MC_Eta_Decay/dpi0pip_1"]
+analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\pi^+\\pi^-\\pi^0$"]["data"] = ["/BESIII_2017_I1469067/d01-x01-y01",
+ "/BESIII_2017_I1469067/d01-x01-y02",
+ "/BESIII_2017_I1469067/d01-x01-y03"]
+analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\pi^+\\pi^-\\pi^0$"]["MC" ] = ["/MC_Eta_Decay/dpi0pim_1","/MC_Eta_Decay/dpippim_1",
+ "/MC_Eta_Decay/dpi0pip_1"]
analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\gamma \\pi^+\\pi^-$"]["MC" ] =["/MC_Eta_Decay/mpimgamma_1","/MC_Eta_Decay/mpipgamma_1",
"/MC_Eta_Decay/mpippim_1","/MC_Eta_Decay/photonenergy_1"]
analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\gamma \\pi^+\\pi^-$"]["data"] = ["/BESIII_2018_I1641075/d01-x01-y05","/CRYSTAL_BARREL_1997_I456942/d01-x01-y01"]
analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\gamma\\gamma\\pi^0$"]["MC" ] = ["/MC_Eta_Decay/mgammagamma_1","/MC_Eta_Decay/mpi0gamma_1"]
analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\gamma\\gamma\\pi^0$"]["data" ] = ["/BESIII_2016_I1504943/d01-x01-y01",
"/BESIII_2016_I1504943/d01-x01-y02",
"/BESIII_2016_I1504943/d01-x01-y03",
"/BESIII_2016_I1504943/d02-x01-y01"]
+analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\pi^0\\pi^0\\pi^0$"]["data"] = ["/BESIII_2015_I1376484/d03-x01-y01",
+ "/BESIII_2017_I1469067/d01-x01-y04",
+ "/BESIII_2018_I1623555/d01-x01-y01",
+ "/BESIII_2018_I1623555/d01-x01-y02",
+ "/BESIII_2018_I1623555/d03-x01-y01",
+ "/BESIII_2018_I1623555/d04-x01-y01"]
analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\pi^0\\pi^0\\pi^0$"]["MC" ] = ["/MC_Eta_Decay/dpi0pi0_1"]
+analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\eta\\pi^0\\pi^0$"]["data"] = ["/BESIII_2022_I2105430/d01-x01-y01",
+ "/BESIII_2022_I2105430/d02-x01-y01",
+ "/BESIII_2022_I2105430/d03-x01-y01",
+ "/BESIII_2022_I2105430/d04-x01-y01",]
analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\eta\\pi^0\\pi^0$"]["MC" ] = ["/MC_Eta_Decay/dpi0eta","/MC_Eta_Decay/dpi0pi0_2"]
+analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\eta\\pi^+\\pi^-$"]["data"] = ["/BESIII_2018_I1623555/d02-x01-y01",
+ "/BESIII_2018_I1623555/d02-x01-y02",
+ "/BESIII_2018_I1623555/d03-x01-y02",
+ "/BESIII_2018_I1623555/d04-x01-y02"]
analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\eta\\pi^+\\pi^-$"]["MC" ] = ["/MC_Eta_Decay/dpimeta","/MC_Eta_Decay/dpipeta",
"/MC_Eta_Decay/dpippim_2"]
+analyses["HadronDecays"][331]["Modes"]["$\\eta^\\prime\\to\\pi^+\\pi^-e^+e^-$"]["data"] = ["/BESIII_2020_I1830421/d01-x01-y02"]
# omega
analyses["HadronDecays"][223] = { "Modes" : {"$\\omega\\to\\pi^+\\pi^-\\pi^0$" : {},
"$\\omega\\to e^+e^-\\pi^0$" : {},
"$\\omega\\to \\mu^+\\mu^-\\pi^0$" : {},}}
-analyses["HadronDecays"][223]["Modes"]["$\\omega\\to\\pi^+\\pi^-\\pi^0$"]["MC"] = ["/MC_OmegaPhia1_3Pion_Decay/dalitz_1","/MC_OmegaPhia1_3Pion_Decay/m0_1",
- "/MC_OmegaPhia1_3Pion_Decay/mminus_1","/MC_OmegaPhia1_3Pion_Decay/mplus_1",
- "/MC_OmegaPhia1_3Pion_Decay/xhist_1","/MC_OmegaPhia1_3Pion_Decay/yhist_1"]
+analyses["HadronDecays"][223]["Modes"]["$\\omega\\to\\pi^+\\pi^-\\pi^0$"]["data"] = ["/BESIII_2018_I1703033/d01-x01-y01",
+ "/BESIII_2018_I1703033/d01-x01-y02",
+ "/BESIII_2018_I1703033/d01-x01-y03",
+ "/BESIII_2018_I1703033/d01-x01-y04",]
+analyses["HadronDecays"][223]["Modes"]["$\\omega\\to\\pi^+\\pi^-\\pi^0$"]["MC" ] = ["/MC_OmegaPhia1_3Pion_Decay/dalitz_1","/MC_OmegaPhia1_3Pion_Decay/m0_1",
+ "/MC_OmegaPhia1_3Pion_Decay/mminus_1","/MC_OmegaPhia1_3Pion_Decay/mplus_1",
+ "/MC_OmegaPhia1_3Pion_Decay/xhist_1","/MC_OmegaPhia1_3Pion_Decay/yhist_1",
+ "/BESIII_2018_I1703033/dalitz"]
analyses["HadronDecays"][223]["Modes"]["$\\omega\\to e^+e^-\\pi^0$"]["MC"] = ["/MC_Meson_Meson_Leptons_Decay/h_223p_111p_11_mPf",
"/MC_Meson_Meson_Leptons_Decay/h_223p_111p_11_mPfbar",
"/MC_Meson_Meson_Leptons_Decay/h_223p_111p_11_mff"]
analyses["HadronDecays"][223]["Modes"]["$\\omega\\to \\mu^+\\mu^-\\pi^0$"]["MC"] = ["/MC_Meson_Meson_Leptons_Decay/h_223p_111p_13_mPf",
"/MC_Meson_Meson_Leptons_Decay/h_223p_111p_13_mPfbar",
"/MC_Meson_Meson_Leptons_Decay/h_223p_111p_13_mff"]
analyses["HadronDecays"][223]["Modes"]["$\\omega\\to \\mu^+\\mu^-\\pi^0$"]["data"] = ["/NA60_2016_I1452485/d02-x01-y01"]
analyses["HadronDecays"][223]["Modes"]["$\\omega\\to e^+e^-\\pi^0$"]["data"] = ["/A2_2017_I1486671/d02-x01-y01"]
# phi
analyses["HadronDecays"][333] = { "Modes" : {"$\\phi\\to\\pi^+\\pi^-\\pi^0$" : {},
"$\\phi\\to e^+e^-\\pi^0$" : {},
"$\\phi\\to e^+e^-\\eta$" : {},
"$\\phi\\to \\mu^+\\mu-\\gamma$" : {},
"$\\phi\\to \\pi^0\\pi^0\\gamma$" : {},
"$\\phi\\to \\eta\\pi^0\\gamma$" : {},
"$\\phi\\to \\mu^+\\mu^-\\pi^0$" : {},
"$\\phi\\to \\mu^+\\mu^-\\eta$" : {},}}
analyses["HadronDecays"][333]["Modes"]["$\\phi\\to\\pi^+\\pi^-\\pi^0$"]["MC"] = ["/MC_OmegaPhia1_3Pion_Decay/dalitz_2","/MC_OmegaPhia1_3Pion_Decay/m0_2",
"/MC_OmegaPhia1_3Pion_Decay/mminus_2","/MC_OmegaPhia1_3Pion_Decay/mplus_2",
"/MC_OmegaPhia1_3Pion_Decay/xhist_2","/MC_OmegaPhia1_3Pion_Decay/yhist_2"]
analyses["HadronDecays"][333]["Modes"]["$\\phi\\to\\pi^+\\pi^-\\pi^0$"]["data"] = ["/SND_2001_I558279/d01-x01-y01","/SND_2001_I558279/d02-x01-y01"]
analyses["HadronDecays"][333]["Modes"]["$\\phi\\to e^+e^-\\pi^0$"]["MC"] = ["/MC_Meson_Meson_Leptons_Decay/h_333p_111p_11_mPf",
"/MC_Meson_Meson_Leptons_Decay/h_333p_111p_11_mPfbar",
"/MC_Meson_Meson_Leptons_Decay/h_333p_111p_11_mff"]
analyses["HadronDecays"][333]["Modes"]["$\\phi\\to e^+e^-\\pi^0$"]["data"] = ["/KLOE2_2016_I1416825/d01-x01-y01"]
analyses["HadronDecays"][333]["Modes"]["$\\phi\\to \\mu^+\\mu^-\\pi^0$"]["MC"] = ["/MC_Meson_Meson_Leptons_Decay/h_333p_111p_13_mPf",
"/MC_Meson_Meson_Leptons_Decay/h_333p_111p_13_mPfbar",
"/MC_Meson_Meson_Leptons_Decay/h_333p_111p_13_mff"]
analyses["HadronDecays"][333]["Modes"]["$\\phi\\to e^+e^-\\eta$"]["MC"] = ["/MC_Meson_Meson_Leptons_Decay/h_333p_221p_11_mPf",
"/MC_Meson_Meson_Leptons_Decay/h_333p_221p_11_mPfbar",
"/MC_Meson_Meson_Leptons_Decay/h_333p_221p_11_mff"]
analyses["HadronDecays"][333]["Modes"]["$\\phi\\to e^+e^-\\eta$"]["data"] = ["/KLOE2_2014_I1317236/d01-x01-y01"]
analyses["HadronDecays"][333]["Modes"]["$\\phi\\to \\mu^+\\mu^-\\eta$"]["MC"] = ["/MC_Meson_Meson_Leptons_Decay/h_333p_221p_13_mPf",
"/MC_Meson_Meson_Leptons_Decay/h_333p_221p_13_mPfbar",
"/MC_Meson_Meson_Leptons_Decay/h_333p_221p_13_mff"]
analyses["HadronDecays"][333]["Modes"]["$\\phi\\to \\pi^0\\pi^0\\gamma$"]["data"] = ["/KLOE_2002_I585183/d01-x01-y01","/SND_2000_I525398/d01-x01-y01"]
analyses["HadronDecays"][333]["Modes"]["$\\phi\\to \\eta\\pi^0\\gamma$" ]["data"] = ["/KLOE_2009_I818106/d01-x01-y01","/SND_2000_I527094/d01-x01-y01"]
analyses["HadronDecays"][333]["Modes"]["$\\phi\\to \\mu^+\\mu-\\gamma$"]["MC"]=["/MC_Meson_Meson_Leptons_Decay/h2_333p_22p_13_mff","/MC_Meson_Meson_Leptons_Decay/h2_333p_22p_13_mVfbar",
"/MC_Meson_Meson_Leptons_Decay/h2_333p_22p_13_mVf"]
# a_1+
analyses["HadronDecays"][20213] = { "Modes" : { "$a_1^+\\to\\pi^+\\pi^0\\pi^0$" : {},
"$a_1^+\\to\\pi^+\\pi^-\\pi^+$" : {},}}
analyses["HadronDecays"][20213]["Modes"]["$a_1^+\\to\\pi^+\\pi^0\\pi^0$"]["MC"] = ["/MC_OmegaPhia1_3Pion_Decay/dalitz1","/MC_OmegaPhia1_3Pion_Decay/hist1A",
"/MC_OmegaPhia1_3Pion_Decay/hist1B"]
analyses["HadronDecays"][20213]["Modes"]["$a_1^+\\to\\pi^+\\pi^-\\pi^+$"]["MC"] = ["/MC_OmegaPhia1_3Pion_Decay/dalitz3","/MC_OmegaPhia1_3Pion_Decay/hist3A",
"/MC_OmegaPhia1_3Pion_Decay/hist3B"]
# a_10
analyses["HadronDecays"][20113] = { "Modes" : { "$a_1^0\\to\\pi^0\\pi^0\\pi^0$" : {},
"$a_1^0\\to\\pi^+\\pi^-\\pi^0$" : {},}}
analyses["HadronDecays"][20113]["Modes"]["$a_1^0\\to\\pi^0\\pi^0\\pi^0$"]["MC"] = ["/MC_OmegaPhia1_3Pion_Decay/dalitz0","/MC_OmegaPhia1_3Pion_Decay/hist0"]
analyses["HadronDecays"][20113]["Modes"]["$a_1^0\\to\\pi^+\\pi^-\\pi^0$"]["MC"] = ["/MC_OmegaPhia1_3Pion_Decay/dalitz2","/MC_OmegaPhia1_3Pion_Decay/hist2A",
"/MC_OmegaPhia1_3Pion_Decay/hist2B" ,"/MC_OmegaPhia1_3Pion_Decay/hist2C"]
# charm decays
# D+
-analyses["HadronDecays"][411] = { "Mult" : {},
+analyses["HadronDecays"][411] = { "BR" : ["PDG_DP"],
+ "Mult" : {},
"Spectrum" : {},
"Modes" : { "$D^+\\to\\bar{K}^0e^+\\nu_e$" : {},
"$D^+\\to\\pi^0e^+\\nu_e$" : {},
"$D^+\\to \\bar{K}_1(1270)^0e^+\\nu_e$" : {},
"$D^+\\to\\bar{K}^0\\mu^+\\nu_\\mu$" : {},
"$D^+\\to\\pi^0\\mu^+\\nu_\\mu$" : {},
"$D^+\\to \\bar{K}_1(1270)^0\\mu^+\\nu_\\mu$" : {},
"$D^+\\to\\eta e^+\\nu_e$" : {},
"$D^+\\to\\eta\\mu^+\\nu_\\mu$" : {},
"$D^+\\to\\eta^\\prime e^+\\nu_e$" : {},
"$D^+\\to\\eta^\\prime\\mu^+\\nu_\\mu$" : {},
"$D^+\\to\\rho^0 e^+\\nu_e$" : {},
"$D^+\\to\\rho^0\\mu^+\\nu_\\mu$" : {},
"$D^+\\to\\omega e^+\\nu_e$" : {},
"$D^+\\to\\omega\\mu^+\\nu_\\mu$" : {},
"$D^+\\to\\bar{K}^{*0}e^+\\nu_e$" : {},
"$D^+\\to\\bar{K}^{*0}\\mu^+\\nu_\\mu$" : {},
"$D^+\\to\\bar{K}_2^{*0}e^+\\nu_e$" : {},
"$D^+\\to\\bar{K}_2^{*0}\\mu^+\\nu_\\mu$" : {},
- "$D^+\\to K^-\\pi^+\\pi^+$" : {},
- "$D^+\\to K^+\\pi^-\\pi^+$" : {},
- "$D^+\\to\\bar{K}^0\\pi^+\\pi^0$" : {},
+ "$D^+\\to K^-\\pi^+\\pi^+$" : {},
+ "$D^+\\to K^+\\pi^+\\pi^-$" : {},
+ "$D^+\\to\\bar{K}^0\\pi^+\\pi^0$" : {},
+ "$D^+\\to K^+K^-\\pi^+$" : {},
+ "$D^+\\to K^+K^+K^-$" : {},
+ "$D^+\\to\\bar{K}^0\\pi^+\\pi^+\\pi^-$" : {},
+ "$D^+\\to K^+K^0_S\\pi^0$" : {},
+ "$D^+\\to K^0_S\\pi^+\\omega$" : {},
+ "$D^+\\to \\pi^+\\pi^+\\pi^-$" : {},
+ "$D^+\\to \\pi^+\\pi^0\\pi^0$" : {},
+ "$D^+\\to 2\\pi^+\\pi^-\\pi^0$" : {},
+ "$D^+\\to 3\\pi^+2\\pi^-$" : {},
+ "$D^+\\to 3\\pi^+2\\pi^-\\pi^0$" : {},
+ "$D^+\\to K^0_S\\pi^+\\eta^\\prime$" : {},
}}
analyses["HadronDecays"][411]["Mult"][221] = ["/CLEOC_2006_I728043/d01-x01-y01"]
analyses["HadronDecays"][411]["Mult"][331] = ["/CLEOC_2006_I728043/d02-x01-y01"]
analyses["HadronDecays"][411]["Mult"][333] = ["/CLEOC_2006_I728043/d03-x01-y01"]
analyses["HadronDecays"][411]["Spectrum"][221] = ["/CLEOC_2006_I728043/d04-x01-y01"]
analyses["HadronDecays"][411]["Spectrum"][333] = ["/CLEOC_2006_I728043/d05-x01-y01"]
analyses["HadronDecays"][411]["Spectrum"][11] = ["/CLEOC_2006_I715096/d01-x01-y01"]
-analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}^0e^+\\nu_e$" ]["data"] = ["/BESIII_2017_I1519425/d01-x01-y01","/CLEOC_2009_I823313/d01-x01-y04",
- "/CLEOC_2008_I769777/d01-x01-y04"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}^0e^+\\nu_e$" ]["data"] = ["/BESIII_2017_I1519425/d01-x01-y01",
+ "/CLEOC_2009_I823313/d01-x01-y04",
+ "/CLEOC_2008_I769777/d01-x01-y04",]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}^0e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_311m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_311m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_311p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_311p_11p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}^0\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_311m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_311m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_311p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_311p_13p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\pi^0e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_111p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_111p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_111p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_111p_11p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\pi^0\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_111p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_111p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_111p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_111p_13p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\pi^0e^+\\nu_e$" ]["data"] = ["/BESIII_2017_I1519425/d02-x01-y01","/CLEOC_2009_I823313/d01-x01-y03",
"/CLEOC_2008_I769777/d01-x01-y02"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\pi^0\\mu^+\\nu_\\mu$" ]["data"] = ["/BESIII_2018_I1655158/d01-x01-y01"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to \\bar{K}_1(1270)^0e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_10313m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_10313m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_10313p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_10313p_11p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to \\bar{K}_1(1270)^0\\mu^+\\nu_\\mu$"]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_10313m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_10313m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_10313p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_10313p_13p_scale"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^-\\pi^+\\pi^+$" ]["data"] = ["/CLEOC_2008_I780363/d01-x01-y01",
+ "/CLEOC_2008_I780363/d01-x02-y01",
+ "/E691_1992_I342947/d01-x01-y01",
+ "/E691_1992_I342947/d01-x01-y02",
+ "/E791_2002_I585322/d01-x01-y01",
+ "/E791_2002_I585322/d01-x01-y02",
+ "/FOCUS_2007_I750701/d01-x01-y01",
+ "/FOCUS_2007_I750701/d01-x01-y02",
+ "/MARKIII_1987_I247266/d04-x01-y01",
+ "/MARKIII_1987_I247266/d04-x01-y02",
+ "/MARKIII_1987_I247266/d04-x01-y03"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^-\\pi^+\\pi^+$" ]["MC" ] = ["/MC_D_Dalitz/dalitz3","/MC_D_Dalitz/h_Kpiall3",
"/MC_D_Dalitz/h_Kpihigh3","/MC_D_Dalitz/h_Kpilow3",
- "/MC_D_Dalitz/h_pipi3"]
-analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^+\\pi^-\\pi^+$" ]["MC" ] = ["/MC_D_Dalitz/dalitz5","/MC_D_Dalitz/h_kppim5",
- "/MC_D_Dalitz/h_kppip5","/MC_D_Dalitz/h_pippim5",]
+ "/MC_D_Dalitz/h_pipi3","/E691_1992_I342947/dalitz1",
+ "/E791_2002_I585322/dalitz",
+ "/FOCUS_2007_I750701/dalitz",
+ "/MARKIII_1987_I247266/dalitz4"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^+\\pi^+\\pi^-$" ]["data"] = ["/FOCUS_2004_I654030/d01-x01-y01",
+ "/FOCUS_2004_I654030/d01-x01-y02"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^+\\pi^+\\pi^-$" ]["MC" ] = ["/MC_D_Dalitz/dalitz5","/MC_D_Dalitz/h_kppim5",
+ "/MC_D_Dalitz/h_kppip5","/MC_D_Dalitz/h_pippim5",
+ "/FOCUS_2004_I654030/dalitz_1"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}^0\\pi^+\\pi^0$" ]["data"] = ["/BESIII_2014_I1277070/d01-x01-y01",
+ "/BESIII_2014_I1277070/d01-x01-y02",
+ "/BESIII_2014_I1277070/d01-x01-y03",
+ "/MARKIII_1987_I247266/d03-x01-y01",
+ "/MARKIII_1987_I247266/d03-x01-y02",
+ "/MARKIII_1987_I247266/d03-x01-y03",]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}^0\\pi^+\\pi^0$" ]["MC" ] = ["/MC_D_Dalitz/dalitz4","/MC_D_Dalitz/h_Kpi04",
- "/MC_D_Dalitz/h_Kpip4","/MC_D_Dalitz/h_pipi4"]
-analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\eta e^+\\nu_e$" ]["data" ] = ["/CLEOC_2011_I875526/d01-x01-y01","/CLEOC_2011_I875526/d01-x01-y02","/BESIII_2018_I1662660/d01-x01-y01"]
+ "/MC_D_Dalitz/h_Kpip4","/MC_D_Dalitz/h_pipi4",
+ "/BESIII_2014_I1277070/dalitz",
+ "/MARKIII_1987_I247266/dalitz3"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\eta e^+\\nu_e$" ]["data" ] = ["/CLEOC_2011_I875526/d01-x01-y01",
+ "/CLEOC_2011_I875526/d01-x01-y02",
+ "/BESIII_2018_I1662660/d01-x01-y01"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\eta e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_221p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_221p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_221p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_221p_11p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\eta\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_221p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_221p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_221p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_221p_13p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\eta^\\prime e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_331p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_331p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_331p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_331p_11p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\eta^\\prime\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_331p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_331p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_331p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_331p_13p_scale"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\rho^0 e^+\\nu_e$" ]["data"] = ["/BESIII_2019_I1694530/d01-x01-y06",
+ "/BESIII_2019_I1694530/d01-x01-y07",
+ "/BESIII_2019_I1694530/d01-x01-y08",
+ "/BESIII_2019_I1694530/d01-x01-y09",
+ "/BESIII_2019_I1694530/d01-x01-y10"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\rho^0 e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_113p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_113p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_113p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_113p_11p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\rho^0\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_113p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_113p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_113p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_113p_13p_scale"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\omega e^+\\nu_e$" ]["data"] = ["/BESIII_2015_I1386254/d01-x01-y01",
+ "/BESIII_2015_I1386254/d01-x01-y02",
+ "/BESIII_2015_I1386254/d01-x01-y03",
+ "/BESIII_2015_I1386254/d01-x01-y04",]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\omega e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_223p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_223p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_223p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_223p_11p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\omega\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_223p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_223p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_223p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_223p_13p_scale"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}^{*0}e^+\\nu_e$" ]["data"] = ["/BABAR_2010_I879997/d01-x01-y01",
+ "/BABAR_2010_I879997/d01-x01-y02",
+ "/BABAR_2010_I879997/d01-x01-y03",
+ "/BABAR_2010_I879997/d01-x01-y04",
+ "/BABAR_2010_I879997/d01-x01-y05",
+ "/BABAR_2010_I879997/d02-x01-y01",
+ "/BABAR_2010_I879997/d02-x01-y02",
+ "/BABAR_2010_I879997/d02-x01-y03",
+ "/BABAR_2010_I879997/d02-x01-y04",
+ "/BABAR_2010_I879997/d03-x01-y01",
+ "/BABAR_2010_I879997/d03-x01-y02",
+ "/BABAR_2010_I879997/d03-x01-y03",
+ "/BABAR_2010_I879997/d03-x01-y04",
+ "/BABAR_2010_I879997/d04-x01-y01",
+ "/BABAR_2010_I879997/d04-x01-y02",
+ "/BABAR_2010_I879997/d04-x01-y03",
+ "/BABAR_2010_I879997/d04-x01-y04",
+ "/BABAR_2010_I879997/d05-x01-y01",
+ "/BABAR_2010_I879997/d05-x01-y02",
+ "/BABAR_2010_I879997/d05-x01-y03",
+ "/BABAR_2010_I879997/d05-x01-y04",
+ "/BESIII_2016_I1411645/d03-x01-y01",
+ "/BESIII_2016_I1411645/d03-x01-y02",
+ "/BESIII_2016_I1411645/d03-x01-y03",
+ "/BESIII_2016_I1411645/d03-x01-y04",
+ "/BESIII_2016_I1411645/d03-x01-y05",
+ "/BESIII_2016_I1411645/d03-x01-y06"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}^{*0}e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_313m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_313m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_313p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_313p_11p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}^{*0}\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_313m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_313m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_313p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_313p_13p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}_2^{*0}e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_315m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_315m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_315p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_315p_11p_scale"]
analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}_2^{*0}\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_411p_315m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_411p_315m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_411m_315p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_411m_315p_13p_scale"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^+K^-\\pi^+$" ]["data"] = ["/BABAR_2013_I1206605/d01-x01-y01",
+ "/BABAR_2013_I1206605/d01-x01-y02",
+ "/BABAR_2013_I1206605/d01-x01-y03",
+ "/BABAR_2013_I1206605/d01-x01-y04",
+ "/CLEO_2008_I791716/d01-x01-y01",
+ "/CLEO_2008_I791716/d01-x01-y02",
+ "/CLEO_2008_I791716/d01-x01-y03"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^+K^-\\pi^+$" ]["MC" ] = ["/BABAR_2013_I1206605/dalitz",
+ "/CLEO_2008_I791716/dalitz"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to\\bar{K}^0\\pi^+\\pi^+\\pi^-$" ]["data"] = ["/BESIII_2019_I1714778/d01-x01-y01",
+ "/BESIII_2019_I1714778/d01-x01-y02",
+ "/BESIII_2019_I1714778/d01-x01-y03",
+ "/BESIII_2019_I1714778/d01-x01-y04",
+ "/BESIII_2019_I1714778/d01-x01-y05",
+ "/BESIII_2019_I1714778/d01-x01-y06",
+ "/BESIII_2019_I1714778/d01-x01-y07",
+ "/BESIII_2019_I1714778/d01-x01-y08",
+ "/BESIII_2019_I1714778/d01-x01-y09",]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^+K^0_S\\pi^0$" ]["data"] = ["/BESIII_2021_I1859124/d01-x01-y01",
+ "/BESIII_2021_I1859124/d01-x01-y02",
+ "/BESIII_2021_I1859124/d01-x01-y03",]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^+K^0_S\\pi^0$" ]["MC" ] = ["/BESIII_2021_I1859124/dalitz"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^0_S\\pi^+\\omega$" ]["data"] = ["/BESIII_2021_I1940222/d01-x01-y07",
+ "/BESIII_2021_I1940222/d01-x01-y08",
+ "/BESIII_2021_I1940222/d01-x01-y09"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^0_S\\pi^+\\omega$" ]["MC" ] = ["/BESIII_2021_I1940222/dalitz_3"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to \\pi^+\\pi^+\\pi^-$" ]["data"] = ["/BESIII_2022_I2102455/d05-x01-y01",
+ "/BESIII_2022_I2102455/d05-x01-y02",
+ "/CLEOC_2007_I749602/d01-x01-y01",
+ "/CLEOC_2007_I749602/d01-x01-y02",
+ "/E791_2001_I530320/d01-x01-y01",
+ "/FOCUS_2003_I635446/d02-x01-y01",
+ "/FOCUS_2003_I635446/d02-x01-y02"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to \\pi^+\\pi^+\\pi^-$" ]["MC" ] = ["/CLEOC_2007_I749602/dalitz",
+ "/E791_2001_I530320/dalitz",
+ "/FOCUS_2003_I635446/dalitz2"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to \\pi^+\\pi^0\\pi^0$" ]["data"] = ["/BESIII_2022_I2102455/d06-x01-y01",
+ "/BESIII_2022_I2102455/d06-x01-y02",]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to 2\\pi^+\\pi^-\\pi^0$" ]["data"] = ["/BESIII_2022_I2102455/d07-x01-y01",
+ "/BESIII_2022_I2102455/d07-x01-y02",
+ "/BESIII_2022_I2102455/d07-x01-y03",
+ "/BESIII_2022_I2102455/d07-x01-y04",
+ "/BESIII_2022_I2102455/d07-x01-y05",]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to 3\\pi^+2\\pi^-$" ]["data"] = ["/BESIII_2022_I2102455/d08-x01-y01",
+ "/BESIII_2022_I2102455/d08-x01-y02",
+ "/BESIII_2022_I2102455/d08-x01-y03",
+ "/BESIII_2022_I2102455/d08-x01-y04",]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to 3\\pi^+2\\pi^-\\pi^0$" ]["data"] = ["/BESIII_2022_I2102455/d09-x01-y01",
+ "/BESIII_2022_I2102455/d09-x01-y02",
+ "/BESIII_2022_I2102455/d09-x01-y03",
+ "/BESIII_2022_I2102455/d09-x01-y04",
+ "/BESIII_2022_I2102455/d09-x01-y05",
+ "/BESIII_2022_I2102455/d09-x01-y06",
+ "/BESIII_2022_I2102455/d09-x01-y07",
+ "/BESIII_2022_I2102455/d09-x01-y08",
+ "/BESIII_2022_I2102455/d09-x01-y09",
+ "/BESIII_2022_I2102455/d09-x01-y10",
+ "/BESIII_2022_I2102455/d09-x01-y11",]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^+K^+K^-$" ]["data"] = ["/LHCB_2019_I1720423/d01-x01-y01",
+ "/LHCB_2019_I1720423/d01-x01-y02",
+ "/LHCB_2019_I1720423/d01-x01-y03",
+ "/LHCB_2019_I1720423/d01-x01-y04"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^+K^+K^-$" ]["MC" ] = ["/LHCB_2019_I1720423/dalitz"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^0_S\\pi^+\\eta^\\prime$" ]["data"] = ["/BESIII_2018_I1693610/d01-x01-y07",
+ "/BESIII_2018_I1693610/d01-x01-y08",
+ "/BESIII_2018_I1693610/d01-x01-y09"]
+analyses["HadronDecays"][411]["Modes"]["$D^+\\to K^0_S\\pi^+\\eta^\\prime$" ]["MC" ] = ["/BESIII_2018_I1693610/dalitz_3"]
# D^0
-analyses["HadronDecays"][421] ={ "Mult" : {},
+analyses["HadronDecays"][421] ={ "BR" : ["PDG_D0"],
+ "Mult" : {},
"Spectrum" : {},
- "Modes" : { "$D^0\\to K^-e^+\\nu_e$" : {},
+ "Modes" : { "$D^0\\to K^-e^+\\nu_e$" : {},
"$D^0\\to K^-\\mu^+\\nu_\\mu$" : {},
"$D^0\\to K^{*-}e^+\\nu_e$" : {},
"$D^0\\to K^{*-}\\mu^+\\nu_\\mu$" : {},
"$D^0\\to K^{*-}_2e^+\\nu_e$" : {},
"$D^0\\to K^{*-}_2\\mu^+\\nu_\\mu$" : {},
"$D^0\\to K_1(1270)^{-}e^+\\nu_e$" : {},
"$D^0\\to K_1(1270)^{-}\\mu^+\\nu_\\mu$": {},
"$D^0\\to \\pi^-e^+\\nu_e$" : {},
"$D^0\\to \\pi^-\\mu^+\\nu_\\mu$" : {},
"$D^0\\to \\rho^-e^+\\nu_e$" : {},
"$D^0\\to \\rho^-\\mu^+\\nu_\\mu$" : {},
"$D^0\\to K^-\\pi^+\\pi^0$" : {},
"$D^0\\to \\bar{K}^0\\pi^+\\pi^-$" : {},
"$D^0\\to \\eta\\pi^+\\pi^-$" : {},
+ "$D^0\\to \\eta\\eta\\pi^0$" : {},
+ "$D^0\\to \\pi^+\\pi^-\\pi^0$" : {},
+ "$D^0\\to \\pi^+\\pi^-2\\pi^0$" : {},
+ "$D^0\\to 2\\pi^+2\\pi^-$" : {},
+ "$D^0\\to 2\\pi^+2\\pi^-\\pi^0$" : {},
+ "$D^0\\to 2\\pi^+2\\pi^-2\\pi^0$" : {},
+ "$D^0\\to K^+K^-\\pi^0$" : {},
+ "$D^0\\to K^-\\pi^+\\eta$" : {},
+ "$D^0\\to K^0_S\pi^0\\eta$" : {},
+ "$D^0\\to K^-\\pi^+\\eta^\\prime$" : {},
+ "$D^0\\to K^0_S\\pi^0\\eta^\\prime$" : {},
+ "$D^0\\to K^-\\pi^+\\pi^+\\pi^-$" : {},
+ "$D^0\\to K^-\\pi^+\\pi^0\\pi^0$" : {},
+ "$D^0\\to K^+K^-\\pi^+\\pi^-$" : {},
+ "$D^0\\to K^0_SK^+K^-$" : {},
+ "$D^0\\to K^-\\pi^+\\omega$" : {},
+ "$D^0\\to K^0_S\pi^0\\omega$" : {},
+ "$D^0\\to \\omega\\phi$" : {},
+ "$D^0\\to \pi^+\\pi^0\\omega$" : {},
+ "$D^0\\to K^0_SK^-\pi^+$" : {},
+ "$D^0\\to K^0_SK^+\pi^-$" : {},
+ "$D^0\\to K^+K^-K^+\\pi^-$" : {},
}}
analyses["HadronDecays"][421]["Mult"][221] = ["/CLEOC_2006_I728043/d01-x01-y02"]
analyses["HadronDecays"][421]["Mult"][331] = ["/CLEOC_2006_I728043/d02-x01-y02"]
analyses["HadronDecays"][421]["Mult"][333] = ["/CLEOC_2006_I728043/d03-x01-y02"]
analyses["HadronDecays"][421]["Spectrum"][221] = ["/CLEOC_2006_I728043/d04-x01-y02"]
analyses["HadronDecays"][421]["Spectrum"][333] = ["/CLEOC_2006_I728043/d05-x01-y02"]
analyses["HadronDecays"][421]["Spectrum"][11] = ["/CLEOC_2006_I715096/d01-x01-y02"]
-analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\eta\\pi^+\\pi^-$"]["data"] = ["/CLEOC_2008_I779705/d01-x01-y01","/CLEOC_2008_I779705/d01-x01-y02"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\eta\\pi^+\\pi^-$" ]["data"] = ["/CLEOC_2008_I779705/d01-x01-y01",
+ "/CLEOC_2008_I779705/d01-x01-y02"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\eta\\eta\\pi^0$" ]["data"] = ["/BESIII_2018_I1662665/d01-x01-y01"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\eta\\eta\\pi^0$" ]["MC" ] = ["/BESIII_2018_I1662665/dalitz"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^{*-}e^+\\nu_e$" ]["data"] = ["/BESIII_2018_I1705754/d01-x01-y01",
+ "/BESIII_2018_I1705754/d01-x01-y02",
+ "/BESIII_2018_I1705754/d01-x01-y03",
+ "/BESIII_2018_I1705754/d01-x01-y04",
+ "/BESIII_2018_I1705754/d01-x01-y05"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^{*-}e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_323m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_323m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_323p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_323p_11p_scale"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^{*-}\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_323m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_323m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_323p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_323p_13p_scale"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^{*-}_2e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_325m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_325m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_325p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_325p_11p_scale"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^{*-}_2\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_325m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_325m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_325p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_325p_13p_scale"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to K_1(1270)^{-}e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_10323m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_10323m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_10323p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_10323p_11p_scale"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to K_1(1270)^{-}\\mu^+\\nu_\\mu$"]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_10323m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_10323m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_10323p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_10323p_13p_scale"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-e^+\\nu_e$" ]["data"] = ["/BESIII_2015_I1391138/d01-x01-y03",
"/BABAR_2007_I1091435/d01-x01-y01",
"/CLEOC_2009_I823313/d01-x01-y02",
- "/CLEOC_2008_I769777/d01-x01-y03"]
+ "/CLEOC_2008_I769777/d01-x01-y03",
+ "/CLEO_2004_I654843/d01-x01-y01"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_321m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_321m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_321p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_321p_11p_scale"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\mu^+\\nu_\\mu$" ]["data"] = ["/BESIII_2018_I1697371/d01-x01-y01"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_321m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_321m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_321p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_321p_13p_scale"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\pi^-e^+\\nu_e$" ]["data"] = ["/BABAR_2015_I1334693/d01-x01-y01",
"/BESIII_2015_I1391138/d02-x01-y03",
"/CLEOC_2009_I823313/d01-x01-y01",
- "/CLEOC_2008_I769777/d01-x01-y01"]
+ "/CLEOC_2008_I769777/d01-x01-y01",
+ "/CLEO_2004_I654843/d01-x01-y02"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\pi^-\\mu^+\\nu_\\mu$" ]["data"] = ["/BESIII_2018_I1655158/d02-x01-y01"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\pi^-e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_211m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_211m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_211p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_211p_11p_scale"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\pi^-\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_211m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_211m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_211p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_211p_13p_scale"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\rho^-e^+\\nu_e$" ]["data"] = ["/BESIII_2019_I1694530/d01-x01-y01",
+ "/BESIII_2019_I1694530/d01-x01-y02",
+ "/BESIII_2019_I1694530/d01-x01-y03",
+ "/BESIII_2019_I1694530/d01-x01-y04",
+ "/BESIII_2019_I1694530/d01-x01-y05",
+ "/CLEO_2013_I1081165/d01-x01-y01",
+ "/CLEO_2013_I1081165/d01-x01-y02",
+ "/CLEO_2013_I1081165/d01-x01-y03",
+ "/CLEO_2013_I1081165/d01-x01-y04"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\rho^-e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_213m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_213m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_213p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_213p_11p_scale"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\rho^-\\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_421p_213m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_421p_213m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_421m_213p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_421m_213p_13p_scale"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\pi^+\\pi^0$" ]["MC" ] = ["/MC_D_Dalitz/dalitz2","/MC_D_Dalitz/h_minus2",
- "/MC_D_Dalitz/h_neutral2","/MC_D_Dalitz/h_pipi2"]
+ "/MC_D_Dalitz/h_neutral2","/MC_D_Dalitz/h_pipi2",
+ "/E691_1992_I342947/dalitz2",
+ "/MARKIII_1987_I247266/dalitz1"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\pi^+\\pi^0$" ]["data"] = ["/BABAR_2006_I722905/d01-x01-y01",
+ "/BABAR_2006_I722905/d02-x01-y01",
+ "/E691_1992_I342947/d01-x01-y03",
+ "/E691_1992_I342947/d01-x01-y04",
+ "/E691_1992_I342947/d01-x01-y05",
+ "/MARKIII_1987_I247266/d01-x01-y01",
+ "/MARKIII_1987_I247266/d01-x01-y02",
+ "/MARKIII_1987_I247266/d01-x01-y03",
+ "/CLEOII_2001_I537154/d01-x01-y01",
+ "/CLEOII_2001_I537154/d01-x02-y01",
+ "/CLEOII_2001_I537154/d01-x03-y01"]
analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\bar{K}^0\\pi^+\\pi^-$" ]["MC" ] = ["/MC_D_Dalitz/dalitz1","/MC_D_Dalitz/h_minus1",
- "/MC_D_Dalitz/h_pipi1","/MC_D_Dalitz/h_plus1"]
-analyses["HadronDecays"][431] = { "Mult" : {},
+ "/MC_D_Dalitz/h_pipi1","/MC_D_Dalitz/h_plus1",
+ "/BABAR_2010_I853279/dalitz1",
+ "/CLEOC_2011_I913909/dalitz",
+ "/CLEO_2003_I633196/dalitz",
+ "/E691_1992_I342947/dalitz3",
+ "/MARKIII_1987_I247266/dalitz2"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\bar{K}^0\\pi^+\\pi^-$" ]["data"] = ["/BABAR_2010_I853279/d01-x01-y01",
+ "/BABAR_2010_I853279/d01-x01-y02",
+ "/BABAR_2010_I853279/d01-x01-y03",
+ "/CLEOC_2011_I913909/d01-x01-y01",
+ "/CLEOC_2011_I913909/d01-x01-y02",
+ "/CLEO_2003_I633196/d01-x01-y01",
+ "/CLEO_2003_I633196/d01-x01-y02",
+ "/CLEO_2003_I633196/d01-x01-y03",
+ "/E691_1992_I342947/d01-x01-y06",
+ "/E691_1992_I342947/d01-x01-y07",
+ "/E691_1992_I342947/d01-x01-y08",
+ "/MARKIII_1987_I247266/d02-x01-y01",
+ "/MARKIII_1987_I247266/d02-x01-y02",
+ "/MARKIII_1987_I247266/d02-x01-y03"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\pi^+\\pi^-\\pi^0$" ]["data"] = ["/BABAR_2007_I747154/d01-x01-y01",
+ "/BABAR_2007_I747154/d01-x01-y02",
+ "/BABAR_2016_I1441203/d01-x01-y01",
+ "/BABAR_2016_I1441203/d01-x01-y02",
+ "/BABAR_2016_I1441203/d01-x01-y03",
+ "/BESIII_2022_I2102455/d01-x01-y01",
+ "/BESIII_2022_I2102455/d01-x01-y02",
+ "/BESIII_2022_I2102455/d01-x01-y03",
+ "/CLEO_2005_I679349/d01-x01-y01",
+ "/CLEO_2005_I679349/d01-x01-y02",
+ "/CLEO_2005_I679349/d01-x01-y03"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\pi^+\\pi^-\\pi^0$" ]["MC" ] = ["/BABAR_2007_I747154/dalitz",
+ "/BABAR_2016_I1441203/dalitz",
+ "/CLEO_2005_I679349/dalitz",
+ "/MC_D_Dalitz/h_pipi5",
+ "/MC_D_Dalitz/h_pipi6",
+ "/MC_D_Dalitz/h_pipi7",
+ "/MC_D_Dalitz/dalitz8"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\pi^+\\pi^-2\\pi^0$" ]["data"] = ["/BESIII_2022_I2102455/d02-x01-y01",
+ "/BESIII_2022_I2102455/d02-x01-y02",
+ "/BESIII_2022_I2102455/d02-x01-y03",
+ "/BESIII_2022_I2102455/d02-x01-y04",
+ "/BESIII_2022_I2102455/d02-x01-y05",
+ "/BESIII_2022_I2102455/d02-x01-y06",
+ "/BESIII_2022_I2102455/d02-x01-y07"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to 2\\pi^+2\\pi^-$" ]["data"] = ["/CLEO_2017_I1519168/d01-x01-y01",
+ "/CLEO_2017_I1519168/d01-x01-y02",
+ "/CLEO_2017_I1519168/d01-x01-y03",
+ "/CLEO_2017_I1519168/d01-x01-y04",
+ "/CLEO_2017_I1519168/d01-x01-y05",
+ "/CLEO_2017_I1519168/d01-x01-y06",
+ "/CLEO_2017_I1519168/d01-x01-y07",
+ "/CLEO_2017_I1519168/d01-x01-y08",
+ "/FOCUS_2007_I741543/d01-x01-y01",
+ "/FOCUS_2007_I741543/d01-x01-y02",
+ "/FOCUS_2007_I741543/d01-x01-y03",
+ "/FOCUS_2007_I741543/d01-x01-y04",
+ "/FOCUS_2007_I741543/d02-x01-y01"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to 2\\pi^+2\\pi^-\\pi^0$" ]["data"] = ["/BESIII_2022_I2102455/d03-x01-y01",
+ "/BESIII_2022_I2102455/d03-x01-y02",
+ "/BESIII_2022_I2102455/d03-x01-y03",
+ "/BESIII_2022_I2102455/d03-x01-y04",
+ "/BESIII_2022_I2102455/d03-x01-y05",
+ "/BESIII_2022_I2102455/d03-x01-y06",
+ "/BESIII_2022_I2102455/d03-x01-y07",
+ "/BESIII_2022_I2102455/d03-x01-y08",
+ "/BESIII_2022_I2102455/d03-x01-y09",]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to 2\\pi^+2\\pi^-2\\pi^0$" ]["data"] = ["/BESIII_2022_I2102455/d04-x01-y01",
+ "/BESIII_2022_I2102455/d04-x01-y02",
+ "/BESIII_2022_I2102455/d04-x01-y03",
+ "/BESIII_2022_I2102455/d04-x01-y04",
+ "/BESIII_2022_I2102455/d04-x01-y05",
+ "/BESIII_2022_I2102455/d04-x01-y06",
+ "/BESIII_2022_I2102455/d04-x01-y07",
+ "/BESIII_2022_I2102455/d04-x01-y08",
+ "/BESIII_2022_I2102455/d04-x01-y09",
+ "/BESIII_2022_I2102455/d04-x01-y10",
+ "/BESIII_2022_I2102455/d04-x01-y11",
+ "/BESIII_2022_I2102455/d04-x01-y12",
+ "/BESIII_2022_I2102455/d04-x01-y13",
+ "/BESIII_2022_I2102455/d04-x01-y14"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^+K^-\\pi^0$" ]["data"] = ["/BABAR_2007_I749390/d01-x01-y01",
+ "/BABAR_2007_I749390/d01-x01-y02",
+ "/BABAR_2007_I749390/d01-x01-y03"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^+K^-\\pi^0$" ]["MC" ] = ["/BABAR_2007_I749390/dalitz",
+ "/BABAR_2016_I1441203/dalitz"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\pi^+\\eta$" ]["MC" ] = ["/BELLE_2020_I1785816/dalitz"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\pi^+\\eta$" ]["data"] = ["/BELLE_2020_I1785816/d01-x01-y01",
+ "/BELLE_2020_I1785816/d01-x01-y02",
+ "/BELLE_2020_I1785816/d01-x01-y03"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_S\pi^0\\eta$" ]["data"] = ["/CLEO_2004_I649917/d01-x01-y01",
+ "/CLEO_2004_I649917/d01-x01-y02",
+ "/CLEO_2004_I649917/d01-x01-y03"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_S\pi^0\\eta$" ]["MC" ] = ["/CLEO_2004_I649917/dalitz"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\pi^+\\eta^\\prime$" ]["MC" ] = ["/BESIII_2018_I1693610/dalitz_1"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\pi^+\\eta^\\prime$" ]["data"] = ["/BESIII_2018_I1693610/d01-x01-y01",
+ "/BESIII_2018_I1693610/d01-x01-y02",
+ "/BESIII_2018_I1693610/d01-x01-y03"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_S\\pi^0\\eta^\\prime$" ]["data"] = ["/BESIII_2018_I1693610/d01-x01-y04",
+ "/BESIII_2018_I1693610/d01-x01-y05",
+ "/BESIII_2018_I1693610/d01-x01-y06"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_S\\pi^0\\eta^\\prime$" ]["MC" ] = ["/BESIII_2018_I1693610/dalitz_2"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\pi^+\\pi^+\\pi^-$" ]["data"] = ["/BESIII_2017_I1511280/d01-x01-y01",
+ "/BESIII_2017_I1511280/d01-x01-y02",
+ "/BESIII_2017_I1511280/d01-x01-y03",
+ "/BESIII_2017_I1511280/d01-x01-y04",
+ "/BESIII_2017_I1511280/d01-x01-y05",
+ "/BESIII_2017_I1511280/d01-x01-y06",
+ "/BESIII_2017_I1511280/d01-x01-y07",
+ "/BESIII_2017_I1511280/d01-x01-y08"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\pi^+\\pi^0\\pi^0$" ]["data"] = ["/BESIII_2019_I1725265/d01-x01-y01",
+ "/BESIII_2019_I1725265/d01-x01-y02",
+ "/BESIII_2019_I1725265/d01-x01-y03",
+ "/BESIII_2019_I1725265/d01-x01-y04"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^+K^-\\pi^+\\pi^-$" ]["data"] = ["/CLEO_2012_I1086166/d01-x01-y01",
+ "/CLEO_2012_I1086166/d01-x01-y02",
+ "/CLEO_2012_I1086166/d01-x01-y03",
+ "/CLEO_2012_I1086166/d01-x01-y04",
+ "/CLEO_2012_I1086166/d01-x01-y05",
+ "/CLEO_2012_I1086166/d01-x01-y06",
+ "/CLEO_2012_I1086166/d02-x01-y01",
+ "/CLEO_2012_I1086166/d02-x01-y02",
+ "/CLEO_2012_I1086166/d02-x01-y03",
+ "/CLEO_2012_I1086166/d02-x01-y04",
+ "/CLEO_2017_I1519168/d02-x01-y01",
+ "/CLEO_2017_I1519168/d02-x01-y02",
+ "/CLEO_2017_I1519168/d02-x01-y03",
+ "/CLEO_2017_I1519168/d02-x01-y04",
+ "/CLEO_2017_I1519168/d02-x01-y05",
+ "/CLEO_2017_I1519168/d02-x01-y06",
+ "/CLEO_2017_I1519168/d03-x01-y01",
+ "/CLEO_2017_I1519168/d03-x01-y02",
+ "/CLEO_2017_I1519168/d03-x01-y03",
+ "/CLEO_2017_I1519168/d03-x01-y04",
+ "/FOCUS_2004_I663820/d01-x01-y01",
+ "/FOCUS_2004_I663820/d01-x01-y02",
+ "/FOCUS_2004_I663820/d01-x01-y03",
+ "/FOCUS_2004_I663820/d01-x01-y04",
+ "/LHCB_2018_I1704426/d01-x01-y01",
+ "/LHCB_2018_I1704426/d01-x01-y02"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_SK^+K^-$" ]["data"] = ["/BABAR_2010_I853279/d01-x01-y04",
+ "/BABAR_2010_I853279/d01-x01-y05",
+ "/BABAR_2010_I853279/d01-x01-y06",
+ "/BESIII_2020_I1799437/d01-x01-y01",
+ "/BESIII_2020_I1799437/d01-x01-y02",
+ "/BESIII_2020_I1799437/d01-x01-y03"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_SK^+K^-$" ]["MC" ] = ["/BABAR_2010_I853279/dalitz2",
+ "/BESIII_2020_I1799437/dalitz"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\pi^+\\omega$" ]["data"] = ["/BESIII_2021_I1940222/d01-x01-y01",
+ "/BESIII_2021_I1940222/d01-x01-y02",
+ "/BESIII_2021_I1940222/d01-x01-y03"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^-\\pi^+\\omega$" ]["MC" ] = ["/BESIII_2021_I1940222/dalitz_1"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_S\pi^0\\omega$" ]["data"] = ["/BESIII_2021_I1940222/d01-x01-y04",
+ "/BESIII_2021_I1940222/d01-x01-y05",
+ "/BESIII_2021_I1940222/d01-x01-y06"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_S\pi^0\\omega$" ]["MC" ] = ["/BESIII_2021_I1940222/dalitz_2"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to \\omega\\phi$" ]["data"] = ["/BESIII_2022_I1900094/d01-x01-y01",
+ "/BESIII_2022_I1900094/d01-x01-y02"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to \pi^+\\pi^0\\omega$" ]["data"] = ["/CLEO_2009_I822856/d01-x01-y01"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_SK^-\pi^+$" ]["data"] = ["/CLEO_2012_I1094160/d01-x01-y01",
+ "/CLEO_2012_I1094160/d01-x01-y02",
+ "/CLEO_2012_I1094160/d01-x01-y03",
+ "/CLEO_2012_I1094160/d01-x01-y04",
+ "/CLEO_2012_I1094160/d01-x01-y05",
+ "/CLEO_2012_I1094160/d01-x01-y06",
+ "/LHCB_2016_I1394391/d01-x01-y01",
+ "/LHCB_2016_I1394391/d01-x01-y02",
+ "/LHCB_2016_I1394391/d01-x01-y03"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_SK^-\pi^+$" ]["MC" ] = ["/CLEO_2012_I1094160/dalitz_1",
+ "/LHCB_2016_I1394391/dalitz_1"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_SK^+\pi^-$" ]["data"] = ["/CLEO_2012_I1094160/d02-x01-y01",
+ "/CLEO_2012_I1094160/d02-x01-y02",
+ "/CLEO_2012_I1094160/d02-x01-y03",
+ "/CLEO_2012_I1094160/d02-x01-y04",
+ "/CLEO_2012_I1094160/d02-x01-y05",
+ "/CLEO_2012_I1094160/d02-x01-y06",
+ "/LHCB_2016_I1394391/d02-x01-y01",
+ "/LHCB_2016_I1394391/d02-x01-y02",
+ "/LHCB_2016_I1394391/d02-x01-y03"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^0_SK^+\pi^-$" ]["MC" ] = ["/CLEO_2012_I1094160/dalitz_2",
+ "/LHCB_2016_I1394391/dalitz_2"]
+analyses["HadronDecays"][421]["Modes"]["$D^0\\to K^+K^-K^+\\pi^-$" ]["data"] = ["/FOCUS_2003_I626320/d01-x01-y01",
+ "/FOCUS_2003_I626320/d01-x01-y02"]
+# D_s decays
+analyses["HadronDecays"][431] = { "BR" : ["PDG_DS"],
+ "Mult" : {},
"Spectrum" : {},
"Modes" : { "$D_s^+\\to \\eta e^+\\nu_e$" : {},
"$D_s^+\\to \\eta \\mu^+\\nu_\\mu$" : {},
"$D_s^+\\to \\eta^\\prime e^+\\nu_e$" : {},
"$D_s^+\\to \\eta^\\prime \\mu^+\\nu_\\mu$" : {},
"$D_s^+\\to \\phi e^+\\nu_e$" : {},
"$D_s^+\\to \\phi \\mu^+\\nu_\\mu$" : {},
"$D_s^+\\to K^0 e^+\\nu_e$" : {},
"$D_s^+\\to K^0 \\mu^+\\nu_\\mu$" : {},
"$D_s^+\\to K^{*0} e^+\\nu_e$" : {},
"$D_s^+\\to K^{*0} \\mu^+\\nu_\\mu$" : {},
- "$D_s^+\\to K^+\\pi^-\\pi^+$" : {},
+ "$D_s^+\\to \\pi^0\\pi^0 e^+\\nu_e$" : {},
+ "$D_s^+\\to K^+\\pi^+\\pi^-$" : {},
+ "$D_s^+\\to \bar{K}^0\\pi^+\\pi^0$" : {},
+ "$D_s^+\\to \\pi^+\\pi^+\\pi^-$" : {},
+ "$D_s^+\\to K^+K^-\\pi^+$" : {},
+ "$D_s^+\\to \\pi^+\\pi^0\\eta$" : {},
+ "$D_s^+\\to \\pi^+\\pi^0\\eta^\\prime$" : {},
+ "$D_s^+\\to \\pi^+\\pi^0\\pi^0$" : {},
+ "$D_s^+\\to \\pi^+\\pi^+\\pi^-\\eta$" : {},
+ "$D_s^+\\to K^0_SK^-\\pi^+\\pi^+$" : {},
+ "$D_s^+\\to K^+K^-\\pi^+\\pi^0$" : {},
+ "$D_s^+\\to K^+\\pi^+\\pi^-\\pi^0$" : {},
+ "$D_s^+\\to K^0_SK^0_S\\pi^+$" : {},
+ "$D_s^+\\to K^0_SK^+\\pi^0$" : {},
+ "$D_s^+\\to K^0_S\\pi^+\\pi^0\\pi^0$" : {},
+ "$D_s^+\\to K^+K^-\\pi^+\\pi^+\\pi^-$" : {},
}}
analyses["HadronDecays"][431]["Mult"][221] = ["/CLEOC_2006_I728043/d01-x01-y03"]
analyses["HadronDecays"][431]["Mult"][331] = ["/CLEOC_2006_I728043/d02-x01-y03"]
analyses["HadronDecays"][431]["Mult"][333] = ["/CLEOC_2006_I728043/d03-x01-y03"]
analyses["HadronDecays"][431]["Spectrum"][221] = ["/CLEOC_2006_I728043/d04-x01-y03"]
analyses["HadronDecays"][431]["Spectrum"][333] = ["/CLEOC_2006_I728043/d05-x01-y03"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\eta e^+\\nu_e$" ]["data"] = ["/BESIII_2019_I1712742/d01-x01-y01",
+ "/BESIII_2019_I1712742/d01-x01-y02",
+ "/BESIII_2019_I1712742/d02-x01-y01",
+ "/BESIII_2019_I1712742/d02-x01-y02",]
analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\eta e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_431p_221p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_431p_221p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_431m_221p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_431m_221p_11p_scale"]
analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\eta \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_431p_221p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_431p_221p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_431m_221p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_431m_221p_13p_scale"]
analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\eta^\\prime e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_431p_331p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_431p_331p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_431m_331p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_431m_331p_11p_scale"]
analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\eta^\\prime \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_431p_331p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_431p_331p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_431m_331p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_431m_331p_13p_scale"]
analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\phi e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_431p_333p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_431p_333p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_431m_333p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_431m_333p_11p_scale"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\phi e^+\\nu_e$" ]["data"] = ["/BABAR_2008_I790461/d01-x01-y01",
+ "/BABAR_2008_I790461/d02-x01-y01",
+ "/BABAR_2008_I790461/d02-x01-y02",
+ "/BABAR_2008_I790461/d02-x01-y03",
+ "/BABAR_2008_I790461/d02-x01-y04",]
analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\phi \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_431p_333p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_431p_333p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_431m_333p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_431m_333p_13p_scale"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^0 e^+\\nu_e$" ]["data"] = ["/BESIII_2019_I1702549/d01-x01-y01"]
analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^0 e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_431p_311p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_431p_311p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_431m_311m_11p_energy",
"/MC_Semi_Leptonic_Decay/h_431m_311m_11p_scale"]
analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^0 \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_431p_311p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_431p_311p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_431m_311m_13p_energy",
"/MC_Semi_Leptonic_Decay/h_431m_311m_13p_scale"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^{*0} e^+\\nu_e$" ]["data"] = ["/BESIII_2019_I1702549/d01-x01-y03",
+ "/BESIII_2019_I1702549/d01-x01-y04",
+ "/BESIII_2019_I1702549/d01-x01-y05",
+ "/BESIII_2019_I1702549/d01-x01-y06",
+ "/BESIII_2019_I1702549/d01-x01-y07",]
analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^{*0} e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_431p_313p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_431p_313p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_431m_313m_11p_energy",
"/MC_Semi_Leptonic_Decay/h_431m_313m_11p_scale"]
analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^{*0} \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_431p_313p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_431p_313p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_431m_313m_13p_scale",
"/MC_Semi_Leptonic_Decay/h_431m_313m_13p_energy"]
-analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^+\\pi^-\\pi^+$" ]["MC" ] = ["/MC_D_Dalitz/dalitz6","/MC_D_Dalitz/h_kppim6",
- "/MC_D_Dalitz/h_kppip6","/MC_D_Dalitz/h_pippim6"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\pi^0\\pi^0 e^+\\nu_e$" ]["data"] = ["/BESIII_2022_I2038523/d01-x01-y01"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^+\\pi^+\\pi^-$" ]["data"] = ["/BESIII_2022_I2084294/d01-x01-y01",
+ "/BESIII_2022_I2084294/d01-x01-y02",
+ "/BESIII_2022_I2084294/d01-x01-y03",
+ "/FOCUS_2004_I654030/d02-x01-y01",
+ "/FOCUS_2004_I654030/d02-x01-y02"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^+\\pi^+\\pi^-$" ]["MC" ] = ["/MC_D_Dalitz/dalitz6","/MC_D_Dalitz/h_kppim6",
+ "/MC_D_Dalitz/h_kppip6","/MC_D_Dalitz/h_pippim6",
+ "/BESIII_2022_I2084294/dalitz",
+ "/FOCUS_2004_I654030/dalitz_2"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\pi^+\\pi^+\\pi^-$" ]["data"] = ["/BABAR_2008_I792597/d01-x01-y01",
+ "/BABAR_2008_I792597/d01-x01-y02",
+ "/BABAR_2008_I792597/d01-x01-y03",
+ "/BABAR_2008_I792597/d01-x01-y04",
+ "/BESIII_2021_I1909391/d01-x01-y01",
+ "/BESIII_2021_I1909391/d01-x01-y02",
+ "/BESIII_2021_I1909391/d01-x01-y03",
+ "/BESIII_2021_I1909391/d01-x01-y04",
+ "/E791_2001_I530319/d01-x01-y01",
+ "/FOCUS_2003_I635446/d01-x01-y01",
+ "/FOCUS_2003_I635446/d01-x01-y02"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\pi^+\\pi^+\\pi^-$" ]["MC" ] = ["/BABAR_2008_I792597/dalitz",
+ "/BESIII_2021_I1909391/dalitz",
+ "/E791_2001_I530319/dalitz",
+ "/FOCUS_2003_I635446/dalitz1"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\pi^+\\pi^0\\pi^0$" ]["data"] = ["/BESIII_2021_I1929365/d01-x01-y01",
+ "/BESIII_2021_I1929365/d01-x01-y02",
+ "/BESIII_2021_I1929365/d01-x01-y03",]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\pi^+\\pi^0\\pi^0$" ]["MC" ] = ["/BESIII_2021_I1929365/dalitz"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^+K^-\\pi^+$" ]["data"] = ["/BABAR_2010_I878120/d01-x01-y01",
+ "/BABAR_2010_I878120/d01-x01-y02",
+ "/BABAR_2010_I878120/d01-x01-y03",
+ "/BABAR_2010_I878120/d01-x01-y04",
+ "/BESIII_2021_I1830524/d01-x01-y01",
+ "/BESIII_2021_I1830524/d01-x01-y02",
+ "/BESIII_2021_I1830524/d01-x01-y03",
+ "/BESIII_2021_I1830524/d01-x01-y04"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^+K^-\\pi^+$" ]["MC" ] = ["/BABAR_2010_I878120/dalitz",
+ "/BESIII_2021_I1830524/dalitz",
+ "/MC_D_Dalitz/h_kmpip1",
+ "/MC_D_Dalitz/h_kpkm1",
+ "/MC_D_Dalitz/h_kppip7",
+ "/MC_D_Dalitz/dalitz7"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\pi^+\\pi^0\\eta$" ]["data"] = ["/BESIII_2019_I1724547/d01-x01-y01",
+ "/BESIII_2019_I1724547/d01-x01-y02",
+ "/BESIII_2019_I1724547/d01-x01-y03",
+ "/BESIII_2019_I1724547/d01-x01-y04",
+ "/BESIII_2019_I1724547/d01-x01-y05",]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\pi^+\\pi^0\\eta$" ]["MC" ] = ["/BESIII_2019_I1724547/dalitz"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\pi^+\\pi^0\\eta^\\prime$" ]["data"] = ["/BESIII_2022_I2030993/d01-x01-y01",
+ "/BESIII_2022_I2030993/d01-x01-y02",
+ "/BESIII_2022_I2030993/d01-x01-y03",]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\pi^+\\pi^0\\eta^\\prime$" ]["MC" ] = ["/BESIII_2022_I2030993/dalitz"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \\pi^+\\pi^+\\pi^-\\eta$" ]["data"] = ["/BESIII_2021_I1870322/d01-x01-y01",
+ "/BESIII_2021_I1870322/d01-x01-y02",
+ "/BESIII_2021_I1870322/d01-x01-y03",
+ "/BESIII_2021_I1870322/d01-x01-y04",
+ "/BESIII_2021_I1870322/d01-x01-y05",
+ "/BESIII_2021_I1870322/d01-x01-y06"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^0_SK^-\\pi^+\\pi^+$" ]["data"] = ["/BESIII_2021_I1845444/d01-x01-y01",
+ "/BESIII_2021_I1845444/d01-x01-y02",
+ "/BESIII_2021_I1845444/d01-x01-y03",
+ "/BESIII_2021_I1845444/d01-x01-y04",
+ "/BESIII_2021_I1845444/d01-x01-y05",
+ "/BESIII_2021_I1845444/d01-x01-y06",
+ "/BESIII_2021_I1845444/d01-x01-y07",
+ "/BESIII_2021_I1845444/d01-x01-y08",
+ "/BESIII_2021_I1845444/d01-x01-y09"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^+K^-\\pi^+\\pi^0$" ]["data"] = ["/BESIII_2021_I1849747/d01-x01-y01",
+ "/BESIII_2021_I1849747/d01-x01-y02",
+ "/BESIII_2021_I1849747/d01-x01-y03",
+ "/BESIII_2021_I1849747/d01-x01-y04",
+ "/BESIII_2021_I1849747/d01-x01-y05",
+ "/BESIII_2021_I1849747/d01-x01-y06",
+ "/BESIII_2021_I1849747/d01-x01-y07",
+ "/BESIII_2021_I1849747/d01-x01-y08",
+ "/BESIII_2021_I1849747/d01-x01-y09",
+ "/BESIII_2021_I1849747/d01-x01-y10"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \bar{K}^0\\pi^+\\pi^0$" ]["data"] = ["/BESIII_2021_I1854317/d01-x01-y01",
+ "/BESIII_2021_I1854317/d01-x01-y02",
+ "/BESIII_2021_I1854317/d01-x01-y03"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to \bar{K}^0\\pi^+\\pi^0$" ]["MC" ] = ["/BESIII_2021_I1854317/dalitz"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^0_SK^0_S\\pi^+$" ]["data"] = ["/BESIII_2022_I1945692/d01-x01-y01",
+ "/BESIII_2022_I1945692/d01-x01-y02"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^0_SK^0_S\\pi^+$" ]["MC" ] = ["/BESIII_2022_I1945692/dalitz"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^0_SK^+\\pi^0$" ]["data"] = ["/BESIII_2022_I2070086/d01-x01-y01",
+ "/BESIII_2022_I2070086/d01-x01-y02",
+ "/BESIII_2022_I2070086/d01-x01-y03"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^0_SK^+\\pi^0$" ]["MC" ] = ["/BESIII_2022_I2070086/dalitz"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^+K^-\\pi^+\\pi^+\\pi^-$" ]["data"] = ["/BESIII_2022_I2051683/d01-x01-y01",
+ "/BESIII_2022_I2051683/d01-x01-y02",
+ "/BESIII_2022_I2051683/d01-x01-y03",
+ "/BESIII_2022_I2051683/d01-x01-y04",
+ "/BESIII_2022_I2051683/d01-x01-y05",
+ "/BESIII_2022_I2051683/d01-x01-y06",
+ "/BESIII_2022_I2051683/d01-x01-y07",
+ "/BESIII_2022_I2051683/d01-x01-y08",
+ "/BESIII_2022_I2051683/d01-x01-y09",
+ "/BESIII_2022_I2051683/d01-x01-y10"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^+\\pi^+\\pi^-\\pi^0$" ]["data"] = ["/BESIII_2022_I2088218/d01-x01-y01",
+ "/BESIII_2022_I2088218/d01-x01-y02",
+ "/BESIII_2022_I2088218/d01-x01-y03",
+ "/BESIII_2022_I2088218/d01-x01-y04",
+ "/BESIII_2022_I2088218/d01-x01-y05",
+ "/BESIII_2022_I2088218/d01-x01-y06",
+ "/BESIII_2022_I2088218/d01-x01-y07",
+ "/BESIII_2022_I2088218/d01-x01-y08",
+ "/BESIII_2022_I2088218/d01-x01-y09",
+ "/BESIII_2022_I2088218/d01-x01-y10"]
+analyses["HadronDecays"][431]["Modes"]["$D_s^+\\to K^0_S\\pi^+\\pi^0\\pi^0$" ]["data"] = ["/BESIII_2022_I2088337/d01-x01-y01",
+ "/BESIII_2022_I2088337/d01-x01-y02",
+ "/BESIII_2022_I2088337/d01-x01-y03",
+ "/BESIII_2022_I2088337/d01-x01-y04",
+ "/BESIII_2022_I2088337/d01-x01-y05",
+ "/BESIII_2022_I2088337/d01-x01-y06",
+ "/BESIII_2022_I2088337/d01-x01-y07"]
# D_2
analyses["HadronDecays"][425] = { "Modes" : { "$D^0_2\\to D^+\pi^-$" : {},
"$D^0_2\\to D^{*+}\pi^-$" : {}}}
analyses["HadronDecays"][425]["Modes"]["$D^0_2\\to D^+\pi^-$" ]["data"] = ["/ARGUS_1989_I268577/d03-x01-y01"]
analyses["HadronDecays"][425]["Modes"]["$D^0_2\\to D^{*+}\pi^-$"]["data"] = ["/ARGUS_1989_I280943/d03-x01-y02","/BABAR_2010_I867611/d01-x01-y02",
"/CLEO_1990_I281039/d01-x01-y02","/LHCB_2013_I1243156/d08-x01-y02",
"/CLEOII_1994_I372349/d02-x01-y01"]
analyses["HadronDecays"][415] = { "Modes" : { "$D^+_2\\to D^{*0}\pi^+$" : {}}}
analyses["HadronDecays"][415]["Modes"]["$D^+_2\\to D^{*0}\pi^+$"]["data"] = ["/CLEOII_1994_I378319/d02-x01-y01"]
# D_1
analyses["HadronDecays"][10423] = { "Modes" : { "$D^0_1\\to D^{*+}\pi^-$" : {}}}
analyses["HadronDecays"][10423]["Modes"]["$D^0_1\\to D^{*+}\pi^-$"]["data"] = ["/ARGUS_1989_I280943/d03-x01-y01","/BABAR_2010_I867611/d01-x01-y01",
"/CLEO_1990_I281039/d01-x01-y01","/LHCB_2013_I1243156/d08-x01-y01",
"/CLEOII_1994_I372349/d02-x01-y02"]
analyses["HadronDecays"][10413] = { "Modes" : { "$D^+_1\\to D^{*0}\pi^+$" : {}}}
analyses["HadronDecays"][10413]["Modes"]["$D^+_1\\to D^{*0}\pi^+$"]["data"] = ["/CLEOII_1994_I378319/d03-x01-y01"]
# D_0(2550)
analyses["HadronDecays"][100421] = { "Modes" : { "$D^0(2550)\\to D^{*+}\pi^-$" : {}}}
analyses["HadronDecays"][100421]["Modes"]["$D^0(2550)\\to D^{*+}\pi^-$"]["data"] = ["/BABAR_2010_I867611/d01-x01-y03","/LHCB_2013_I1243156/d10-x01-y01"]
# D_1(2600)
analyses["HadronDecays"][100423] = { "Modes" : { "$D^*_1(2600)^0\\to D^{*+}\pi^-$" : {}}}
analyses["HadronDecays"][100423]["Modes"]["$D^*_1(2600)^0\\to D^{*+}\pi^-$"]["data"] = ["/BABAR_2010_I867611/d01-x01-y04","/LHCB_2013_I1243156/d09-x01-y01"]
# D_3(2750)
analyses["HadronDecays"][20425] = { "Modes" : { "$D_2(2740)^0\\to D^{*+}\pi^-$" : {}}}
analyses["HadronDecays"][20425]["Modes"]["$D_2(2740)^0\\to D^{*+}\pi^-$"]["data"] = ["/LHCB_2013_I1243156/d10-x01-y02"]
# D_3(2750)
analyses["HadronDecays"][427] = { "Modes" : { "$D^*_3(2750)^0\\to D^{*+}\pi^-$" : {}}}
analyses["HadronDecays"][427]["Modes"]["$D^*_3(2750)^0\\to D^{*+}\pi^-$"]["data"] = ["/BABAR_2010_I867611/d01-x01-y05","/LHCB_2013_I1243156/d09-x01-y02"]
# D_s1(2536)
analyses["HadronDecays"][10433] = { "Modes" : { "$D^+_{s1}\\to D^{*+}K^0$" : {},
"$D^+_{s1}\\to D^{*0}K^+$" : {}}}
analyses["HadronDecays"][10433]["Modes"]["$D^+_{s1}\\to D^{*+}K^0$"]["data"]= ["/BABAR_2011_I892421/d01-x01-y01","/BABAR_2011_I892421/d02-x01-y01",
"/BELLE_2008_I762013/d01-x01-y01","/BELLE_2008_I762013/d02-x01-y01",
"/BELLE_2008_I762013/d03-x01-y01","/LHCB_2016_I1414195/d01-x01-y01"]
analyses["HadronDecays"][10433]["Modes"]["$D^+_{s1}\\to D^{*0}K^+$"]["data"]= ["/CLEOII_1993_I352823/d04-x01-y01"]
# D_s1(2460)
analyses["HadronDecays"][20433] = { "Modes" : { "$D^{\\prime+}_{s1}\\to D^{*+}_s\pi^0$" : {}}}
analyses["HadronDecays"][20433]["Modes"]["$D^{\\prime+}_{s1}\\to D^{*+}_s\pi^0$"]["data"]= ["/BABAR_2006_I714447/d05-x01-y01"]
# D_s2
analyses["HadronDecays"][435] = { "Modes" : { "$D^+_{s2}\\to D^{*+}K^0$" : {}}}
analyses["HadronDecays"][435]["Modes"]["$D^+_{s2}\\to D^{*+}K^0$"]["data"]= ["/LHCB_2016_I1414195/d01-x01-y02"]
# D_*1(2700)
analyses["HadronDecays"][100433] = { "Modes" : { "$D^{*+}_{s1}(2700)\\to D^{*+}K^0$" : {}}}
analyses["HadronDecays"][100433]["Modes"]["$D^{*+}_{s1}(2700)\\to D^{*+}K^0$"]["data"]= ["/LHCB_2016_I1414195/d02-x01-y01","/BABAR_2009_I827985/d01-x01-y01"]
# D_*1(2860)
analyses["HadronDecays"][30433] = { "Modes" : { "$D^{*+}_{s1}(2860)\\to D^{*+}K^0$" : {}}}
analyses["HadronDecays"][30433]["Modes"]["$D^{*+}_{s1}(2860)\\to D^{*+}K^0$"]["data"]= ["/LHCB_2016_I1414195/d02-x01-y02","/LHCB_2016_I1414195/d02-x01-y05",
"/BABAR_2009_I827985/d01-x01-y02","/BABAR_2009_I827985/d01-x01-y04"]
# D_*1(2860)
analyses["HadronDecays"][437 ] = { "Modes" : { "$D^{*+}_{s3}(2860)\\to D^{*+}K^0$" : {}}}
analyses["HadronDecays"][437 ]["Modes"]["$D^{*+}_{s3}(2860)\\to D^{*+}K^0$"]["data"]= ["/LHCB_2016_I1414195/d02-x01-y04","/LHCB_2016_I1414195/d02-x01-y05",
"/BABAR_2009_I827985/d01-x01-y03","/BABAR_2009_I827985/d01-x01-y04"]
# B0
analyses["HadronDecays"][511]={ "Spectrum" : {},
"Modes" : { "$B^0\\to\\pi^- e^+\\nu_e$" : {},
"$B^0\\to\\pi^- \\mu^+\\nu_\\mu$" : {},
"$B^0\\to\\rho^- e^+\\nu_e$" : {},
"$B^0\\to\\rho^- \\mu^+\\nu_\\mu$" : {},
"$B^0\\to D^- e^+\\nu_e$" : {},
"$B^0\\to D^- \\mu^+\\nu_\\mu$" : {},
"$B^0\\to D^{*-} e^+\\nu_e$" : {},
"$B^0\\to D^{*-} \\mu^+\\nu_\\mu$" : {},
"$B^0\\to D^{*-}_2 e^+\\nu_e$" : {},
"$B^0\\to D^{*-}_2 \\mu^+\\nu_\\mu$" : {},
"$B^0\\to D^{*-}_0(2400) e^+\\nu_e$" : {},
"$B^0\\to D^{*-}_0(2400) \\mu^+\\nu_\\mu$" : {},
"$B^0\\to D^{-}_1(2430) e^+\\nu_e$" : {},
"$B^0\\to D^{-}_1(2430) \\mu^+\\nu_\\mu$" : {},
"$B^0\\to D^{-}_1(2420) e^+\\nu_e$" : {},
"$B^0\\to D^{-}_1(2420) \\mu^+\\nu_\\mu$" : {},
"$B^0\\to K^{*0} e^+e^-$" : {},
"$B^0\\to K^{*0} \\mu^+\\mu^-$" : {},
"$B^0\\to K^0 e^+e^-$" : {},
"$B^0\\to K^0 \\mu^+\\mu^-$" : {},
- "$B\\to X_s\\gamma$" : {},}}
+ "$B\\to X_s\\gamma$" : {},
+ "$B\\to X_s\\eta$" : {},
+ "$B\\to X_s\\eta^\\prime$" : {},
+ "$B^0\\to D^{*-}\\tau^+\\nu_\\tau$" : {},
+ "$B\\to D^{*}\\tau^+\\nu_\\tau$" : {},
+ "$B^0\\to p\\bar{p}\\pi^0$" : {},
+ "$B^0\\to $K^0_SK^-\\pi^+$" : {},
+ "$B^0\\to $K^0_SK^+\\pi^-$" : {},
+ "$B\\to X_u\\ell^+\\nu_\\ell$" : {},
+ }}
analyses["HadronDecays"][521]={ "Spectrum" : {},
"Modes" : { "$B^+\\to\\pi^0 e^+\\nu_e$" : {},
- "$B^+\\to\\pi^0 \\mu^+\\nu_\\mu$" : {},
- "$B^+\\to\\omega e^+\\nu_e$" : {},
- "$B^+\\to\\omega \\mu^+\\nu_\\mu$" : {},
- "$B^+\\to\\rho^0 e^+\\nu_e$" : {},
- "$B^+\\to\\rho^0 \\mu^+\\nu_\\mu$" : {},
- "$B^+\\to\\eta^\\prime e^+\\nu_e$" : {},
- "$B^+\\to\\eta^\\prime \\mu^+\\nu_\\mu$" : {},
- "$B^+\\to\\eta e^+\\nu_e$" : {},
- "$B^+\\to\\eta \\mu^+\\nu_\\mu$" : {},
- "$B^+\\to\\bar{D}^0 e^+\\nu_e$" : {},
- "$B^+\\to\\bar{D}^0 \\mu^+\\nu_\\mu$" : {},
- "$B^+\\to\\bar{D}^{*0} e^+\\nu_e$" : {},
- "$B^+\\to\\bar{D}^{*0} \\mu^+\\nu_\\mu$" : {},
- "$B^+\\to\\bar{D}^{*0}_2 e^+\\nu_e$" : {},
- "$B^+\\to\\bar{D}^{*0}_2 \\mu^+\\nu_\\mu$": {},
- "$B^+\\to\\bar{D}^{*0}_0(2400) e^+\\nu_e$" : {},
- "$B^+\\to\\bar{D}^{*0}_0(2400) \\mu^+\\nu_\\mu$": {},
- "$B^+\\to\\bar{D}^{0}_1(2430) e^+\\nu_e$" : {},
- "$B^+\\to\\bar{D}^{0}_1(2430) \\mu^+\\nu_\\mu$" : {},
- "$B^+\\to\\bar{D}^{0}_1(2420) e^+\\nu_e$" : {},
- "$B^+\\to\\bar{D}^{0}_1(2420) \\mu^+\\nu_\\mu$" : {},
- "$B^+\\to K^{*+} e^+e^-$" : {},
- "$B^+\\to K^{*+} \\mu^+\\mu^-$" : {},
- "$B^+\\to K^- e^+e^-$" : {},
- "$B^+\\to K^- \\mu^+\\mu^-$" : {},}
-}
+ "$B^+\\to\\pi^0 \\mu^+\\nu_\\mu$" : {},
+ "$B^+\\to\\omega e^+\\nu_e$" : {},
+ "$B^+\\to\\omega \\mu^+\\nu_\\mu$" : {},
+ "$B^+\\to\\rho^0 e^+\\nu_e$" : {},
+ "$B^+\\to\\rho^0 \\mu^+\\nu_\\mu$" : {},
+ "$B^+\\to\\eta^\\prime e^+\\nu_e$" : {},
+ "$B^+\\to\\eta^\\prime \\mu^+\\nu_\\mu$" : {},
+ "$B^+\\to\\eta e^+\\nu_e$" : {},
+ "$B^+\\to\\eta \\mu^+\\nu_\\mu$" : {},
+ "$B^+\\to\\bar{D}^0 e^+\\nu_e$" : {},
+ "$B^+\\to\\bar{D}^0 \\mu^+\\nu_\\mu$" : {},
+ "$B^+\\to\\bar{D}^{*0} e^+\\nu_e$" : {},
+ "$B^+\\to\\bar{D}^{*0} \\mu^+\\nu_\\mu$" : {},
+ "$B^+\\to\\bar{D}^{*0}_2 e^+\\nu_e$" : {},
+ "$B^+\\to\\bar{D}^{*0}_2 \\mu^+\\nu_\\mu$": {},
+ "$B^+\\to\\bar{D}^{*0}_0(2400) e^+\\nu_e$" : {},
+ "$B^+\\to\\bar{D}^{*0}_0(2400) \\mu^+\\nu_\\mu$": {},
+ "$B^+\\to\\bar{D}^{0}_1(2430) e^+\\nu_e$" : {},
+ "$B^+\\to\\bar{D}^{0}_1(2430) \\mu^+\\nu_\\mu$" : {},
+ "$B^+\\to\\bar{D}^{0}_1(2420) e^+\\nu_e$" : {},
+ "$B^+\\to\\bar{D}^{0}_1(2420) \\mu^+\\nu_\\mu$" : {},
+ "$B^+\\to K^{*+} e^+e^-$" : {},
+ "$B^+\\to K^{*+} \\mu^+\\mu^-$" : {},
+ "$B^+\\to K^- e^+e^-$" : {},
+ "$B^+\\to K^- \\mu^+\\mu^-$" : {},
+ "$B^+\\to\\pi^+\\pi^- \\ell^+\\nu_\\ell$" : {},
+ "$B^+\\to\\phi\\phi K^+$" : {},
+ }}
analyses["HadronDecays"][511]["Spectrum"][311 ] = ["/ARGUS_1994_I354224/d01-x01-y01"]
analyses["HadronDecays"][521]["Spectrum"][411 ] = ["/BABAR_2006_I719111/d01-x01-y01","/BABAR_2006_I719111/d01-x01-y02"]
analyses["HadronDecays"][521]["Spectrum"][421 ] = ["/BABAR_2006_I719111/d02-x01-y01","/BABAR_2006_I719111/d02-x01-y02"]
analyses["HadronDecays"][521]["Spectrum"][431 ] = ["/BABAR_2006_I719111/d03-x01-y01","/BABAR_2006_I719111/d03-x01-y02"]
analyses["HadronDecays"][521]["Spectrum"][4122] = ["/BABAR_2006_I719111/d04-x01-y01","/BABAR_2006_I719111/d04-x01-y02"]
analyses["HadronDecays"][511]["Spectrum"][411 ] = ["/BABAR_2006_I719111/d05-x01-y01","/BABAR_2006_I719111/d05-x01-y02",
"/ARGUS_1991_I315059/d05-x01-y01"]
analyses["HadronDecays"][511]["Spectrum"][413 ] = ["/ARGUS_1991_I315059/d07-x01-y01"]
analyses["HadronDecays"][511]["Spectrum"][421 ] = ["/BABAR_2006_I719111/d06-x01-y01","/BABAR_2006_I719111/d06-x01-y02",
"/ARGUS_1991_I315059/d06-x01-y01"]
analyses["HadronDecays"][511]["Spectrum"][431 ] = ["/BABAR_2006_I719111/d07-x01-y01","/BABAR_2006_I719111/d07-x01-y02"]
analyses["HadronDecays"][511]["Spectrum"][4122] = ["/BABAR_2006_I719111/d08-x01-y01","/BABAR_2006_I719111/d08-x01-y02"]
+analyses["HadronDecays"][511]["Spectrum"][11] = ["/CRYSTAL_BALL_1989_I263581/d01-x01-y01"]
-analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\pi^0 e^+\\nu_e$" ]["data"] = ["/BELLE_2013_I1238273/d02-x01-y01"]
+analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\pi^0 e^+\\nu_e$" ]["data"] = ["/BELLE_2013_I1238273/d02-x01-y01",
+ "/BABAR_2011_I855306/d01-x01-y01",
+ "/BABAR_2011_I855306/d01-x01-y03",
+ "/BABAR_2012_I1125973/d02-x01-y01",
+ "/BABAR_2012_I1125973/d02-x01-y02"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\pi^0 e^+\\nu_e$" ]["MC"] = ["/MC_Semi_Leptonic_Decay/h_521p_111p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_111p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_111p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_111p_11p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\pi^0 \\mu^+\\nu_\\mu$" ]["MC"] = ["/MC_Semi_Leptonic_Decay/h_521p_111p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_111p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_111p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_111p_13p_scale"]
-analyses["HadronDecays"][511]["Modes"]["$B^0\\to\\pi^- e^+\\nu_e$" ]["data"] = ["/BELLE_2011_I878990/d01-x01-y01","/BELLE_2013_I1238273/d01-x01-y01"]
+analyses["HadronDecays"][511]["Modes"]["$B^0\\to\\pi^- e^+\\nu_e$" ]["data"] = ["/BELLE_2011_I878990/d01-x01-y01",
+ "/BELLE_2013_I1238273/d01-x01-y01",
+ "/BABAR_2011_I855306/d01-x01-y02",
+ "/BABAR_2012_I1125973/d01-x01-y01",
+ "/BABAR_2012_I1125973/d01-x01-y02"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to\\pi^- e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_211m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_211m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_211p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_211p_11p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to\\pi^- \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_211m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_511p_211m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_511m_211p_13p_scale",
"/MC_Semi_Leptonic_Decay/h_511m_211p_13p_energy"]
-analyses["HadronDecays"][511]["Modes"]["$B^0\\to\\rho^- e^+\\nu_e$" ]["data"] = ["/BELLE_2013_I1238273/d03-x01-y01"]
+analyses["HadronDecays"][511]["Modes"]["$B^0\\to\\rho^- e^+\\nu_e$" ]["data"] = ["/BELLE_2013_I1238273/d03-x01-y01",
+ "/BABAR_2011_I855306/d02-x01-y01",
+ "/BABAR_2011_I855306/d02-x01-y03",]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to\\rho^- e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_213m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_213m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_213p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_213p_11p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to\\rho^- \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_213m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_213m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_213p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_213p_13p_scale"]
-analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\omega e^+\\nu_e$" ]["data"] = ["/BELLE_2013_I1238273/d05-x01-y01","/BABAR_2013_I1116411/d01-x01-y01"]
+analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\omega e^+\\nu_e$" ]["data"] = ["/BELLE_2013_I1238273/d05-x01-y01",
+ "/BABAR_2013_I1116411/d01-x01-y01",
+ "/BABAR_2012_I1125973/d03-x01-y01"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\omega e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521m_223p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_223p_11p_scale",
"/MC_Semi_Leptonic_Decay/h_521p_223p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_223p_11m_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\omega \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521m_223p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_223p_13p_scale",
"/MC_Semi_Leptonic_Decay/h_521p_223p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_223p_13m_scale",]
-analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\rho^0 e^+\\nu_e$" ]["data"] = ["/BELLE_2013_I1238273/d04-x01-y01"]
+analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\rho^0 e^+\\nu_e$" ]["data"] = ["/BELLE_2013_I1238273/d04-x01-y01",
+ "/BABAR_2011_I855306/d02-x01-y02",]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\rho^0 e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_113p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_113p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_113p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_113p_11p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\rho^0 \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_113p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_113p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_113p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_113p_13p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^- e^+\\nu_e$" ]["data"] = ["/BELLE_2015_I1397632/d01-x01-y01"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^- \\mu^+\\nu_\\mu$" ]["data"] = ["/BELLE_2015_I1397632/d01-x01-y02"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^- e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_411m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_411m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_411p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_411p_11p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^- \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_411m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_411m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_411p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_411p_13p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{*-} e^+\\nu_e$" ]["data"] = ["/BELLE_2017_I1512299/d01-x01-y01","/BELLE_2017_I1512299/d02-x01-y01",
- "/BELLE_2017_I1512299/d03-x01-y01","/BELLE_2017_I1512299/d04-x01-y01",]
+ "/BELLE_2017_I1512299/d03-x01-y01","/BELLE_2017_I1512299/d04-x01-y01",
+ "/BELLE_2019_I1693396/d01-x01-y01",
+ "/BELLE_2019_I1693396/d02-x01-y01",
+ "/BELLE_2019_I1693396/d03-x01-y01",
+ "/BELLE_2019_I1693396/d04-x01-y01",]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{*-} e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_413m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_413m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_413p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_413p_11p_scale"]
+analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{*-} \\mu^+\\nu_\\mu$" ]["data" ] = ["/BELLE_2019_I1693396/d01-x01-y02",
+ "/BELLE_2019_I1693396/d02-x01-y02",
+ "/BELLE_2019_I1693396/d03-x01-y02",
+ "/BELLE_2019_I1693396/d04-x01-y02"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{*-} \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_413m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_413m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_413p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_413p_13p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{*-}_2 e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_415m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_415m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_415p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_415p_11p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{*-}_2 \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_415m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_415m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_415p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_415p_13p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\eta^\\prime e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_331p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_331p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_331p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_331p_11p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\eta^\\prime \\mu^+\\nu_\\mu$"]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_331p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_331p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_331p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_331p_13p_scale"]
+analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\eta e^+\\nu_e$" ]["data"] = ["/BABAR_2012_I1125973/d04-x01-y01",
+ "/BABAR_2013_I1247460/d01-x01-y01"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\eta e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_221p_11m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_221p_11m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_221p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_221p_11p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\eta \\mu^+\\nu_\\mu$"]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_221p_13m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_221p_13m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_221p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_221p_13p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^0 e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_421m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_421m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_421p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_421p_11p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^0 \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_421m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_421m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_421p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_421p_13p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^0 e^+\\nu_e$" ]["data"] = ["/BELLE_2015_I1397632/d02-x01-y01"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^0 \\mu^+\\nu_\\mu$" ]["data"] = ["/BELLE_2015_I1397632/d02-x01-y02"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^{*0} e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_423m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_423m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_423p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_423p_11p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^{*0} \\mu^+\\nu_\\mu$"]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_423m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_423m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_423p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_423p_13p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^{*0}_2 e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_425m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_425m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_425p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_425p_11p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^{*0}_2 \\mu^+\\nu_\\mu$"]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_425m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_425m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_425p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_425p_13p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^{*0}_0(2400) e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_10421m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_10421m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_10421p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_10421p_11p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^{*0}_0(2400) \\mu^+\\nu_\\mu$"]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_10421m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_10421m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_10421p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_10421p_13p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^{0}_1(2430) e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_20423m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_20423m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_20423p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_20423p_11p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^{0}_1(2430) \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_20423m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_20423m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_20423p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_20423p_13p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^{0}_1(2420) e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_10423m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_10423m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_10423p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_10423p_11p_scale"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\bar{D}^{0}_1(2420) \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_521p_10423m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_521p_10423m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_521m_10423p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_521m_10423p_13p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{*-}_0(2400) e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_10411m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_10411m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_10411p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_10411p_11p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{*-}_0(2400) \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_10411m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_10411m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_10411p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_10411p_13p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{-}_1(2430) e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_20413m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_20413m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_20413p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_20413p_11p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{-}_1(2430) \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_20413m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_20413m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_20413p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_20413p_13p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{-}_1(2420) e^+\\nu_e$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_10413m_11m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_10413m_11m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_10413p_11p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_10413p_11p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{-}_1(2420) \\mu^+\\nu_\\mu$" ]["MC" ] = ["/MC_Semi_Leptonic_Decay/h_511p_10413m_13m_energy",
"/MC_Semi_Leptonic_Decay/h_511p_10413m_13m_scale",
"/MC_Semi_Leptonic_Decay/h_511m_10413p_13p_energy",
"/MC_Semi_Leptonic_Decay/h_511m_10413p_13p_scale"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to K^{*0} e^+e^-$" ]["MC" ] = ["/MC_Meson_Meson_Leptons_Decay/h2_511p_313p_11_mVf",
"/MC_Meson_Meson_Leptons_Decay/h2_511p_313p_11_mVfbar",
"/MC_Meson_Meson_Leptons_Decay/h2_511p_313p_11_mff"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to K^{*0} \\mu^+\\mu^-$"]["MC" ] = ["/MC_Meson_Meson_Leptons_Decay/h2_511p_313p_13_mVf",
"/MC_Meson_Meson_Leptons_Decay/h2_511p_313p_13_mVfbar",
"/MC_Meson_Meson_Leptons_Decay/h2_511p_313p_13_mff"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to K^0 e^+e^-$" ]["MC" ] = ["/MC_Meson_Meson_Leptons_Decay/h_511p_311p_11_mPf",
"/MC_Meson_Meson_Leptons_Decay/h_511p_311p_11_mPfbar",
"/MC_Meson_Meson_Leptons_Decay/h_511p_311p_11_mff",
"/MC_Meson_Meson_Leptons_Decay/h_511m_311m_11_mPf",
"/MC_Meson_Meson_Leptons_Decay/h_511m_311m_11_mPfbar",
"/MC_Meson_Meson_Leptons_Decay/h_511m_311m_11_mff"]
analyses["HadronDecays"][511]["Modes"]["$B^0\\to K^0 \\mu^+\\mu^-$"]["MC" ] = ["/MC_Meson_Meson_Leptons_Decay/h_511m_311m_13_mPf",
"/MC_Meson_Meson_Leptons_Decay/h_511m_311m_13_mPfbar",
"/MC_Meson_Meson_Leptons_Decay/h_511m_311m_13_mff"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to K^{*+} e^+e^-$" ]["MC" ] = ["/MC_Meson_Meson_Leptons_Decay/h2_521m_323m_11_mVf",
"/MC_Meson_Meson_Leptons_Decay/h2_521m_323m_11_mff",
"/MC_Meson_Meson_Leptons_Decay/h2_521m_323m_11_mVfbar"]
analyses["HadronDecays"][521]["Modes"]["$B^+\\to K^{*+} \\mu^+\\mu^-$"]["MC" ] = []
analyses["HadronDecays"][521]["Modes"]["$B^+\\to K^- e^+e^-$" ]["MC" ] = []
analyses["HadronDecays"][521]["Modes"]["$B^+\\to K^- \\mu^+\\mu^-$" ]["MC" ] = ["/MC_Meson_Meson_Leptons_Decay/h_521m_321m_13_mPfbar",
"/MC_Meson_Meson_Leptons_Decay/h_521m_321m_13_mff",
"/MC_Meson_Meson_Leptons_Decay/h_521m_321m_13_mPf"]
-analyses["HadronDecays"][511]["Modes"]["$B\\to X_s\\gamma$"]["data"]=["/BELLE_2015_I1330289/d01-x01-y02"]
+analyses["HadronDecays"][511]["Modes"]["$B\\to X_s\\gamma$"]["data"]=["/BELLE_2015_I1330289/d01-x01-y02",
+ "/BABAR_2008_I769107/d01-x01-y01",
+ "/BABAR_2012_I1123662/d01-x01-y01",]
+analyses["HadronDecays"][511]["Modes"]["$B\\to X_s\\eta$"]["data"]=["/BELLE_2010_I835104/d01-x01-y01"]
+analyses["HadronDecays"][511]["Modes"]["$B\\to X_s\\eta^\\prime$"]["data"]=["/BABAR_2004_I642355/d01-x01-y01"]
+
+analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\pi^+\\pi^- \\ell^+\\nu_\\ell$"]["data"] = ["/BELLE_2020_I1796822/d01-x01-y01",
+ "/BELLE_2020_I1796822/d02-x01-y01"]
+analyses["HadronDecays"][511]["Modes"]["$B^0\\to D^{*-}\\tau^+\\nu_\\tau$"]["data"]=["/BELLE_2019_I1724068/d01-x01-y01","/BELLE_2019_I1724068/d02-x01-y01"]
+analyses["HadronDecays"][511]["Modes"]["$B\\to D^{*}\\tau^+\\nu_\\tau$"]["data"]=["/BELLE_2018_I1621272/d01-x01-y02"]
+analyses["HadronDecays"][511]["Modes"]["$B^0\\to p\\bar{p}\\pi^0$"]["data"] = ["/BELLE_2019_I1729311/d01-x01-y01",
+ "/BELLE_2019_I1729311/d02-x01-y01",
+ "/BELLE_2019_I1729311/d02-x01-y02"]
+analyses["HadronDecays"][511]["Modes"]["$B^0\\to p\\bar{p}\\pi^0$"]["MC" ] = ["/BELLE_2019_I1729311/dalitz"]
+analyses["HadronDecays"][511]["Modes"]["$B^0\\to $K^0_SK^-\\pi^+$"]["data"] = ["/BELLE_2019_I1729723/d01-x01-y01",
+ "/BELLE_2019_I1729723/d02-x01-y01",
+ "/BELLE_2019_I1729723/d03-x01-y01"]
+analyses["HadronDecays"][511]["Modes"]["$B^0\\to $K^0_SK^+\\pi^-$"]["data"] = ["/BELLE_2019_I1729723/d01-x01-y02",
+ "/BELLE_2019_I1729723/d02-x01-y02",
+ "/BELLE_2019_I1729723/d03-x01-y02"]
+analyses["HadronDecays"][521]["Modes"]["$B^+\\to\\phi\\phi K^+$"]["data"] = ["/BELLE_2021_I1841899/d01-x01-y01",
+ "/BELLE_2021_I1841899/d01-x01-y02"]
+analyses["HadronDecays"][511]["Modes"]["$B\\to X_u\\ell^+\\nu_\\ell$"]["data"] = ["/BELLE_2021_I1895149/d01-x01-y01",
+ "/BELLE_2021_I1895149/d02-x01-y01",
+ "/BELLE_2021_I1895149/d03-x01-y01",
+ "/BELLE_2021_I1895149/d04-x01-y01",
+ "/BELLE_2021_I1895149/d05-x01-y01",
+ "/BELLE_2021_I1895149/d06-x01-y01",
+ "/BELLE_2021_I1895149/d10-x01-y01"]
+# B_s
+analyses["HadronDecays"][531]={ "Spectrum" : {},
+ "Modes" : { "$B_s^0\\to D^{*-}_s\\mu^+\\nu_\\mu$" : {},
+ }}
+analyses["HadronDecays"][531]["Modes"]["$B_s^0\\to D^{*-}_s\\mu^+\\nu_\\mu$"]["data"] = ["/LHCB_2020_I1787090/d01-x01-y01"]
# charmonium
-analyses["HadronDecays"][443] = { "Modes" : { "$J/\\psi\\to\\eta e^+e^-$" : {},
+analyses["HadronDecays"][443] = { "DistChargedMult" : {},
+ "Modes" : { "$J/\\psi\\to\\eta e^+e^-$" : {},
"$J/\\psi\\to\\gamma e^+e^-$" : {},
"$J/\\psi\\to\\gamma \\mu^+\\mu^-$" : {},
"$J/\\psi\\to p\\bar{p}$" : {},
"$J/\\psi\\to n\\bar{n}$" : {},
"$J/\\psi\\to \\Sigma^{*-}\\bar\\Sigma^{*+}$" : {},
"$J/\\psi\\to \\Sigma^{*0}\\bar\\Sigma^{*0}$" : {},
"$J/\\psi\\to \\Sigma^{*+}\\bar\\Sigma^{*-}$" : {},
"$J/\\psi\\to \\Xi^{-}\\bar\\Xi^{+}$" : {},
"$J/\\psi\\to \\Xi^{*-}\\bar\\Xi^{*+}$" : {},
"$J/\\psi\\to \\Xi^{0}\\bar\\Xi^{0}$" : {},
"$J/\\psi\\to \\Lambda^{0}\\bar\\Lambda^{0}$" : {},
"$J/\\psi\\to \\Lambda^{0}\\bar\\Sigma^{0}$" : {},
"$J/\\psi\\to \\Sigma^{0}\\bar\\Sigma^{0}$" : {},
+ "$J/\\psi\\to \\Sigma^{+}\\bar\\Sigma^{-}$" : {},
+ "$J/\\psi\\to \\pi^+\\pi^-\\pi^0$" : {},
+ "$J/\\psi\\to K^+K^-\\pi^0$" : {},
+ "$J/\\psi\\to K^0_SK^\\pm\\pi^\\mp$" : {},
+ "$J/\\psi\\to p\\bar{p}\\eta^\\prime$" : {},
+ "$J/\\psi\\to p\\bar{p}\\pi^0$" : {},
+ "$J/\\psi\\to p\\bar{p}\\eta$" : {},
+ "$J/\\psi\\to p\\bar{p}\\omega$" : {},
+ "$J/\\psi\\to p\\bar{p}\\phi$" : {},
+ "$J/\\psi\\to \\pi^+\\pi^-\\eta^\\prime$" : {},
+ "$J/\\psi\\to \\phi\\eta\\eta^\\prime$" : {},
+ "$J/\\psi\\to n\\bar{p}\\pi^+$" : {},
}}
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to\\eta e^+e^-$" ]["data"] = ["/BESIII_2018_I1697377/d01-x01-y01"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to\\gamma e^+e^-$"]["MC" ] = ["/MC_Meson_Meson_Leptons_Decay/h2_443p_22p_11_mVf",
"/MC_Meson_Meson_Leptons_Decay/h2_443p_22p_11_mVfbar",
"/MC_Meson_Meson_Leptons_Decay/h2_443p_22p_11_mff"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to\\gamma \\mu^+\\mu^-$"]["MC" ] = ["/MC_Meson_Meson_Leptons_Decay/h2_443p_22p_13_mVf",
"/MC_Meson_Meson_Leptons_Decay/h2_443p_22p_13_mVfbar",
"/MC_Meson_Meson_Leptons_Decay/h2_443p_22p_13_mff"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}$" ]["data"] = ["/BESIII_2012_I1113599/d01-x01-y01"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}$" ]["MC"] = ["/BESIII_2012_I1113599/ctheta_p"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to n\\bar{n}$" ]["data"] = ["/BESIII_2012_I1113599/d01-x01-y02"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to n\\bar{n}$" ]["MC"] = ["/BESIII_2012_I1113599/ctheta_n"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\Sigma^{*-}\\bar\\Sigma^{*+}$"]["data"] = ["/BESIII_2016_I1422780/d02-x01-y02","/BESIII_2016_I1422780/d01-x01-y03"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\Sigma^{*0}\\bar\\Sigma^{*0}$"]["data"] = ["/BESIII_2017_I1506414/d01-x01-y01","/BESIII_2017_I1506414/d02-x01-y01"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\Sigma^{*+}\\bar\\Sigma^{*-}$"]["data"] = ["/BESIII_2016_I1422780/d02-x01-y03","/BESIII_2016_I1422780/d01-x01-y03"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\Xi^{-}\\bar\\Xi^{+}$" ]["data"] = ["/BESIII_2016_I1422780/d02-x01-y01","/BESIII_2016_I1422780/d01-x01-y03"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\Xi^{0}\\bar\\Xi^{0}$" ]["data"] = ["/BESIII_2017_I1506414/d01-x01-y02","/BESIII_2017_I1506414/d02-x02-y01"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\Lambda^{0}\\bar\\Lambda^{0}$"]["data"] = ["/BESIII_2017_I1510563/d01-x01-y01","/BESIII_2017_I1510563/d02-x01-y01",
"/BESIII_2019_I1691850/d01-x01-y01","/BESIII_2019_I1691850/d01-x02-y01",
"/BESIII_2019_I1691850/d01-x03-y01","/BESIII_2019_I1691850/d01-x04-y01",
- "/BESIII_2019_I1691850/d01-x05-y01",]
+ "/BESIII_2019_I1691850/d01-x05-y01",
+ "/BESIII_2019_I1691850/d02-x01-y01","/BESIII_2019_I1691850/d02-x01-y02"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\Lambda^{0}\\bar\\Sigma^{0}$" ]["data"] = ["/BESIII_2012_I1121378/d01-x01-y01","/BESIII_2012_I1121378/d01-x01-y02",
"/BESIII_2012_I1121378/d05-x01-y01",]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\Lambda^{0}\\bar\\Lambda^{0}$"]["MC" ] = ["/BESIII_2019_I1691850/T1_n","/BESIII_2019_I1691850/T1_p",
"/BESIII_2019_I1691850/T2_n","/BESIII_2019_I1691850/T2_p",
"/BESIII_2019_I1691850/T3_n","/BESIII_2019_I1691850/T3_p",
"/BESIII_2019_I1691850/T4_n","/BESIII_2019_I1691850/T4_p",
"/BESIII_2019_I1691850/T5_n","/BESIII_2019_I1691850/T5_p",
"/BESIII_2019_I1691850/mu_n","/BESIII_2019_I1691850/mu_p",
"/BESIII_2019_I1691850/cThetaL",]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\Sigma^{0}\\bar\\Sigma^{0}$" ]["data"] = ["/BESIII_2017_I1510563/d01-x01-y03","/BESIII_2017_I1510563/d02-x02-y01"]
analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\Xi^{*-}\\bar\\Xi^{*+}$" ]["data"] = ["/BESIII_2019_I1765606/d02-x01-y01","/BESIII_2019_I1765606/d01-x01-y01"]
-
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\Sigma^{+}\\bar\\Sigma^{-}$" ]["data"] = ["/BESIII_2020_I1791570/d01-x01-y01","/BESIII_2020_I1791570/d01-x01-y02",
+ "/BESIII_2020_I1791570/d02-x01-y01","/BESIII_2020_I1791570/d02-x01-y02",
+ "/BESIII_2020_I1791570/d02-x01-y03","/BESIII_2020_I1791570/d03-x01-y01",
+ "/BESIII_2020_I1791570/d04-x01-y01"]
+analyses["HadronDecays"][443]["DistChargedMult"]["data"] = ["/BESIII_2020_I1800404/d02-x01-y01","/BESIII_2020_I1800404/d02-x01-y02"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\pi^+\\pi^-\\pi^0$" ]["data"] = ["/BABAR_2017_I1512302/d01-x01-y01",
+ "/BABAR_2017_I1512302/d01-x01-y02",
+ "/BESIII_2012_I1088606/d01-x01-y01"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\pi^+\\pi^-\\pi^0$" ]["MC" ] = ["/BABAR_2017_I1512302/dalitz_3pi",
+ "/BESIII_2012_I1088606/dalitz_Jpsi"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to K^+K^-\\pi^0$" ]["data"] = ["/BABAR_2017_I1512302/d02-x01-y01",
+ "/BABAR_2017_I1512302/d02-x01-y02",
+ "/BESIII_2019_I1731057/d01-x01-y01",
+ "/BESIII_2019_I1731057/d01-x01-y02",
+ "/BESIII_2019_I1731057/d02-x01-y01",
+ "/BESIII_2019_I1731057/d02-x01-y02"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to K^+K^-\\pi^0$" ]["MC" ] = ["/BABAR_2017_I1512302/dalitz_K0Kppim",
+ "/BESIII_2019_I1731057/dalitz"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to K^0_SK^\\pm\\pi^\\mp$"]["data"] = ["/BABAR_2017_I1512302/d03-x01-y01",
+ "/BABAR_2017_I1512302/d03-x01-y02",
+ "/BABAR_2017_I1512302/d03-x01-y03"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to K^0_SK^\\pm\\pi^\\mp$"]["MC" ] = ["/BABAR_2017_I1512302/dalitz_KpKmpi"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}\\omega$" ]["data"]=["/BESIII_2013_I1223625/d01-x01-y01",
+ "/BESIII_2013_I1223625/d01-x01-y02",
+ "/BESIII_2013_I1223625/d01-x01-y03"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}\\omega$" ]["MC" ]=["/BESIII_2013_I1223625/dalitz"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}\\phi$" ]["data"]=["/BESIII_2016_I1411448/d01-x01-y01",
+ "/BESIII_2016_I1411448/d01-x01-y02",
+ "/BESIII_2016_I1411448/d01-x01-y03",
+ "/BESIII_2016_I1411448/d01-x01-y04",
+ "/BESIII_2016_I1411448/d01-x01-y05",
+ "/BESIII_2016_I1411448/d01-x01-y06"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}\\phi$" ]["MC" ]=["/BESIII_2016_I1411448/dalitz"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\pi^+\\pi^-\\eta^\\prime$"]["data"]=["/BESIII_2017_I1621266/d01-x01-y01",
+ "/BESIII_2017_I1621266/d01-x01-y02"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\pi^+\\pi^-\\eta^\\prime$"]["MC" ]=["/BESIII_2017_I1621266/dalitz_Jpsi"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}\\eta^\\prime$" ]["data"]=["/BESIII_2019_I1709205/d02-x01-y01",
+ "/BESIII_2019_I1709205/d02-x01-y02",
+ "/BESIII_2019_I1709205/d02-x01-y03",
+ "/BESIII_2019_I1709205/d02-x01-y04",
+ "/BESIII_2019_I1709205/d02-x01-y05",
+ "/BESIII_2019_I1709205/d02-x01-y06",]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}\\eta^\\prime$" ]["MC" ]=["/BESIII_2019_I1709205/dalitz_2"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\phi\\eta\\eta^\\prime$" ]["data"]=["/BESIII_2019_I1712729/d01-x01-y01",
+ "/BESIII_2019_I1712729/d01-x01-y02"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to \\phi\\eta\\eta^\\prime$" ]["MC" ]=["/BESIII_2019_I1712729/dalitz"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to n\\bar{p}\\pi^+$" ]["data"]=["/BESII_2006_I650381/d01-x01-y01",
+ "/BESII_2006_I650381/d01-x01-y02"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to n\\bar{p}\\pi^+$" ]["MC" ]=["/BESII_2006_I650381/dalitz_1",
+ "/BESII_2006_I650381/dalitz_2"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}\\pi^0$" ]["data"]=["/BESII_2009_I819937/d01-x01-y01",
+ "/BESII_2009_I819937/d01-x01-y02"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}\\pi^0$" ]["MC" ]=["/BESII_2009_I819937/dalitz"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}\\eta$" ]["data"]=["/BES_2001_I556330/d01-x01-y01",
+ "/BES_2001_I556330/d02-x01-y01"]
+analyses["HadronDecays"][443]["Modes"]["$J/\\psi\\to p\\bar{p}\\eta$" ]["MC" ]=["/BES_2001_I556330/dalitz"]
# eta_c
-analyses["HadronDecays"][441] = {"DistChargedMult" : {}}
-
+analyses["HadronDecays"][441] = { "BR" : ["PDG_ETAC"],
+ "DistChargedMult" : {},
+ "Modes" : { "$\\eta_c\\to \\pi^+\\pi^-\\eta$" : {},
+ "$\\eta_c\\to \\pi^+\\pi^-\\eta^\\prime$" : {},
+ "$\\eta_c\\to K^+K^-\\eta$" : {},
+ "$\\eta_c\\to K^+K^-\\eta^\\prime$" : {},
+ "$\\eta_c\\to K^+K^-\\pi^0$" : {},
+ "$\\eta_c\\to K^0_SK^\\pm\\pi^\\mp$" : {},}}
analyses["HadronDecays"][441]["DistChargedMult"]["data"] = ["/BESIII_2019_I1724880/d01-x01-y01"]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to \\pi^+\\pi^-\\eta$" ]["data"] = ["/BABAR_2021_I1867843/d03-x01-y01",
+ "/BABAR_2021_I1867843/d03-x01-y02",]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to \\pi^+\\pi^-\\eta$" ]["MC" ] = ["/BABAR_2021_I1867843/dalitz3"]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to \\pi^+\\pi^-\\eta^\\prime$"]["data"] = ["/BABAR_2021_I1867843/d02-x01-y01",
+ "/BABAR_2021_I1867843/d02-x01-y02",]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to \\pi^+\\pi^-\\eta^\\prime$"]["MC" ] = ["/BABAR_2021_I1867843/dalitz2"]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to K^+K^-\\eta$" ]["data"] = ["/BABAR_2014_I1287632/d01-x01-y01",
+ "/BABAR_2014_I1287632/d01-x01-y02",
+ "/BABAR_2014_I1287632/d01-x01-y03",]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to K^+K^-\\eta$" ]["MC" ] = ["/BABAR_2014_I1287632/dalitz_1",]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to K^+K^-\\eta^\\prime$" ]["data"] = ["/BABAR_2021_I1867843/d01-x01-y01",
+ "/BABAR_2021_I1867843/d01-x01-y02",
+ "/BABAR_2021_I1867843/d01-x01-y03",]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to K^+K^-\\eta^\\prime$" ]["MC" ] = ["/BABAR_2021_I1867843/dalitz1",]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to K^+K^-\\pi^0$" ]["data"] = ["/BABAR_2014_I1287632/d02-x01-y01",
+ "/BABAR_2014_I1287632/d02-x01-y02",
+ "/BABAR_2014_I1287632/d02-x01-y03",
+ "/BABAR_2015_I1403544/d04-x01-y01",
+ "/BABAR_2015_I1403544/d04-x01-y02",
+ "/BABAR_2015_I1403544/d04-x01-y03",]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to K^+K^-\\pi^0$" ]["MC" ] = ["/BABAR_2014_I1287632/dalitz_2",
+ "/BABAR_2015_I1403544/dalitz_2"]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to K^0_SK^\\pm\\pi^\\mp$" ]["data"] = ["/BABAR_2015_I1403544/d03-x01-y01",
+ "/BABAR_2015_I1403544/d03-x01-y02",
+ "/BABAR_2015_I1403544/d03-x01-y03",
+ "/BESIII_2012_I1187787/d01-x01-y01",
+ "/BESIII_2012_I1187787/d01-x01-y02",
+ "/BESIII_2012_I1187787/d01-x01-y03"]
+analyses["HadronDecays"][441]["Modes"]["$\\eta_c\\to K^0_SK^\\pm\\pi^\\mp$" ]["MC" ] = ["/BABAR_2015_I1403544/dalitz_1",
+ "/BESIII_2012_I1187787/dalitz"]
+# chi_c0
+analyses["HadronDecays"][10441] = {"BR" : ["PDG_CHIC0"],
+ "DistChargedMult" : {},
+ "Modes" : { "$\\chi_{c0}\\to \\phi\\phi\\eta$" : {},
+ "$\\chi_{c0}\\to \\Sigma^0\\bar{p}K^+$" : {},
+ "$\\chi_{c0}\\to nK^0_S\\bar{\\Lambda}$" : {},
+ "$\\chi_{c0}\\to \\pi^+\\pi^- K^+K^-$" : {},
+ "$\\chi_{c0}\\to \\pi^+\\pi^-\\pi^0\\pi^0$" : {},
+ "$\\chi_{c0}\\to K^\\pm\\pi^\\mp K^0_S\\pi^0$" : {},
+ }}
+analyses["HadronDecays"][10441]["DistChargedMult"]["data"] = ["/BESIII_2020_I1800404/d01-x01-y01"]
+analyses["HadronDecays"][10441]["Modes"]["$\\chi_{c0}\\to \\phi\\phi\\eta$" ]["data"] = ["/BESIII_2020_I1763897/d01-x01-y01",
+ "/BESIII_2020_I1763897/d01-x01-y02"]
+analyses["HadronDecays"][10441]["Modes"]["$\\chi_{c0}\\to \\phi\\phi\\eta$" ]["MC" ] = ["/BESIII_2020_I1763897/dalitz_1"]
+analyses["HadronDecays"][10441]["Modes"]["$\\chi_{c0}\\to \\Sigma^0\\bar{p}K^+$"]["data"] = ["/BESIII_2020_I1818254/d01-x01-y01",
+ "/BESIII_2020_I1818254/d01-x01-y02",
+ "/BESIII_2020_I1818254/d01-x01-y03",]
+analyses["HadronDecays"][10441]["Modes"]["$\\chi_{c0}\\to \\Sigma^0\\bar{p}K^+$"]["MC" ] = ["/BESIII_2020_I1818254/dalitz_1"]
+analyses["HadronDecays"][10441]["Modes"]["$\\chi_{c0}\\to nK^0_S\\bar{\\Lambda}$"]["data"] = ["/BESIII_2021_I1870388/d01-x01-y01",
+ "/BESIII_2021_I1870388/d01-x01-y02",
+ "/BESIII_2021_I1870388/d01-x01-y03"]
+analyses["HadronDecays"][10441]["Modes"]["$\\chi_{c0}\\to nK^0_S\\bar{\\Lambda}$"]["MC" ] = ["/BESIII_2021_I1870388/dalitz_1"]
+analyses["HadronDecays"][10441]["Modes"]["$\\chi_{c0}\\to \\pi^+\\pi^- K^+K^-$"]["data"] = ["/BESII_2005_I690784/d01-x01-y01",
+ "/BESII_2005_I690784/d01-x01-y02",
+ "/BESII_2005_I690784/d01-x01-y03",
+ "/BESII_2005_I690784/d01-x01-y04"]
+analyses["HadronDecays"][10441]["Modes"]["$\\chi_{c0}\\to \\pi^+\\pi^-\\pi^0\\pi^0$"]["data"] = ["/CLEO_2008_I787608/d01-x01-y01",
+ "/CLEO_2008_I787608/d01-x01-y02",]
+analyses["HadronDecays"][10441]["Modes"]["$\\chi_{c0}\\to K^\\pm\\pi^\\mp K^0_S\\pi^0$"]["data"] = ["/CLEO_2008_I787608/d04-x01-y01",
+ "/CLEO_2008_I787608/d04-x01-y02",
+ "/CLEO_2008_I787608/d04-x01-y03",
+ "/CLEO_2008_I787608/d04-x01-y04",]
+# chi_c1
+analyses["HadronDecays"][20443] = { "BR" : ["PDG_CHIC1"],
+ "DistChargedMult" : {},
+ "Modes" : { "$\\chi_{c1}\\to K^+K^-\\eta^\\prime$" : {},
+ "$\\chi_{c1}\\to \\pi^+\\pi^-\\eta$" : {},
+ "$\\chi_{c1}\\to \\pi^+\\pi^-\\eta^\\prime$" : {},
+ "$\\chi_{c1}\\to \\phi\\phi\\eta$" : {},
+ "$\\chi_{c1}\\to \\Sigma^0\\bar{p}K^+$" : {},
+ "$\\chi_{c1}\\to nK^0_S\\bar{\\Lambda}$" : {},
+ "$\\chi_{c1}\\to K^+K^-\\pi^0$" : {},
+ "$\\chi_{c1}\\to K^\\pm K^0_S\\pi^\\mp$" : {},
+ "$\\chi_{c1}\\to \\pi^+\\pi^-\\pi^0\\pi^0$" : {},
+ "$\\chi_{c1}\\to K^\\pm\\pi^\\mp K^0_S\\pi^0$" : {},
+ }}
+analyses["HadronDecays"][20443]["DistChargedMult"]["data"] = ["/BESIII_2020_I1800404/d01-x01-y02"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to K^+K^-\\eta^\\prime$"]["data"] = ["/BESIII_2014_I1280710/d01-x01-y01",
+ "/BESIII_2014_I1280710/d01-x01-y02",
+ "/BESIII_2014_I1280710/d02-x01-y01",
+ "/BESIII_2014_I1280710/d02-x01-y02"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to K^+K^-\\eta^\\prime$"]["MC" ] = ["/BESIII_2014_I1280710/dalitz_1"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to \\pi^+\\pi^-\\eta$" ]["data"] = ["/BESIII_2017_I1490896/d01-x01-y01",
+ "/BESIII_2017_I1490896/d01-x01-y02",
+ "/CLEOC_2011_I929693/d01-x01-y01",
+ "/CLEOC_2011_I929693/d01-x01-y02",
+ "/CLEO_2007_I732065/d01-x01-y01",
+ "/CLEO_2007_I732065/d01-x01-y02",
+ "/CLEO_2007_I732065/d01-x01-y03"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to \\pi^+\\pi^-\\eta$" ]["MC" ] = ["/BESIII_2017_I1490896/dalitz",
+ "/CLEOC_2011_I929693/dalitz_1",
+ "/CLEO_2007_I732065/dalitz_1"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to \\pi^+\\pi^-\\eta^\\prime$"]["data"] = ["/CLEOC_2011_I929693/d02-x01-y01",
+ "/CLEOC_2011_I929693/d02-x01-y02"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to \\pi^+\\pi^-\\eta^\\prime$"]["MC" ] = ["/CLEOC_2011_I929693/dalitz_2"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to \\phi\\phi\\eta$"]["data"] = ["/BESIII_2020_I1763897/d02-x01-y01",
+ "/BESIII_2020_I1763897/d02-x01-y02"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to \\phi\\phi\\eta$"]["MC" ] = ["/BESIII_2020_I1763897/dalitz_2"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to \\Sigma^0\\bar{p}K^+$"]["data"] = ["/BESIII_2020_I1818254/d02-x01-y01",
+ "/BESIII_2020_I1818254/d02-x01-y02",
+ "/BESIII_2020_I1818254/d02-x01-y03",]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to \\Sigma^0\\bar{p}K^+$"]["MC" ] = ["/BESIII_2020_I1818254/dalitz_2"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to nK^0_S\\bar{\\Lambda}$"]["data"] = ["/BESIII_2021_I1870388/d02-x01-y01",
+ "/BESIII_2021_I1870388/d02-x01-y02",
+ "/BESIII_2021_I1870388/d02-x01-y03"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to nK^0_S\\bar{\\Lambda}$"]["MC" ] = ["/BESIII_2021_I1870388/dalitz_2"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to K^+K^-\\pi^0$" ]["data"] = ["/CLEO_2007_I732065/d02-x01-y01",
+ "/CLEO_2007_I732065/d02-x01-y02",
+ "/CLEO_2007_I732065/d02-x01-y03"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to K^+K^-\\pi^0$" ]["MC" ] = ["/CLEO_2007_I732065/dalitz_2"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to K^\\pm K^0_S\\pi^\\mp$"]["data"] = ["/CLEO_2007_I732065/d03-x01-y01",
+ "/CLEO_2007_I732065/d03-x01-y02",
+ "/CLEO_2007_I732065/d03-x01-y03"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to K^\\pm K^0_S\\pi^\\mp$"]["MC" ] = ["/CLEO_2007_I732065/dalitz_3"]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to \\pi^+\\pi^-\\pi^0\\pi^0$"]["data"] = ["/CLEO_2008_I787608/d02-x01-y01",
+ "/CLEO_2008_I787608/d02-x01-y02",]
+analyses["HadronDecays"][20443]["Modes"]["$\\chi_{c1}\\to K^\\pm\\pi^\\mp K^0_S\\pi^0$"]["data"] = ["/CLEO_2008_I787608/d05-x01-y01",
+ "/CLEO_2008_I787608/d05-x01-y02",]
+# chi_c2
+analyses["HadronDecays"][445 ] = { "BR" : ["PDG_CHIC2"],
+ "DistChargedMult" : {},
+ "Modes" : { "$\\chi_{c2}\\to K^+K^-\\eta^\\prime$" : {},
+ "$\\chi_{c2}\\to \\phi\\phi\\eta$" : {},
+ "$\\chi_{c2}\\to \\Sigma^0\\bar{p}K^+$" : {},
+ "$\\chi_{c2}\\to nK^0_S\\bar{\\Lambda}$" : {},
+ "$\\chi_{c2}\\to \\pi^+\\pi^-\\pi^0\\pi^0$" : {},
+ "$\\chi_{c2}\\to K^\\pm\\pi^\\mp K^0_S\\pi^0$" : {},
+ }}
+analyses["HadronDecays"][445 ]["DistChargedMult"]["data"] = ["/BESIII_2020_I1800404/d01-x01-y03"]
+analyses["HadronDecays"][445 ]["Modes"]["$\\chi_{c2}\\to K^+K^-\\eta^\\prime$"]["data"] = ["/BESIII_2014_I1280710/d03-x01-y01",
+ "/BESIII_2014_I1280710/d03-x01-y02",
+ "/BESIII_2014_I1280710/d04-x01-y01",
+ "/BESIII_2014_I1280710/d04-x01-y02"]
+analyses["HadronDecays"][445 ]["Modes"]["$\\chi_{c2}\\to K^+K^-\\eta^\\prime$"]["MC" ] = ["/BESIII_2014_I1280710/dalitz_2"]
+analyses["HadronDecays"][445 ]["Modes"]["$\\chi_{c2}\\to \\phi\\phi\\eta$"]["data"] = ["/BESIII_2020_I1763897/d03-x01-y01",
+ "/BESIII_2020_I1763897/d03-x01-y02"]
+analyses["HadronDecays"][445 ]["Modes"]["$\\chi_{c2}\\to \\phi\\phi\\eta$"]["MC" ] = ["/BESIII_2020_I1763897/dalitz_3"]
+analyses["HadronDecays"][445 ]["Modes"]["$\\chi_{c2}\\to \\Sigma^0\\bar{p}K^+$"]["data"] = ["/BESIII_2020_I1818254/d03-x01-y01",
+ "/BESIII_2020_I1818254/d03-x01-y02",
+ "/BESIII_2020_I1818254/d03-x01-y03",]
+analyses["HadronDecays"][445 ]["Modes"]["$\\chi_{c2}\\to \\Sigma^0\\bar{p}K^+$"]["MC" ] = ["/BESIII_2020_I1818254/dalitz_3"]
+analyses["HadronDecays"][445 ]["Modes"]["$\\chi_{c2}\\to nK^0_S\\bar{\\Lambda}$"]["data"] = ["/BESIII_2021_I1870388/d03-x01-y01",
+ "/BESIII_2021_I1870388/d03-x01-y02",
+ "/BESIII_2021_I1870388/d03-x01-y03"]
+analyses["HadronDecays"][445 ]["Modes"]["$\\chi_{c2}\\to nK^0_S\\bar{\\Lambda}$"]["MC" ] = ["/BESIII_2021_I1870388/dalitz_3"]
+analyses["HadronDecays"][445 ]["Modes"]["$\\chi_{c2}\\to \\pi^+\\pi^-\\pi^0\\pi^0$"]["data"] = ["/CLEO_2008_I787608/d03-x01-y01",
+ "/CLEO_2008_I787608/d03-x01-y02",]
+analyses["HadronDecays"][445 ]["Modes"]["$\\chi_{c2}\\to K^\\pm\\pi^\\mp K^0_S\\pi^0$"]["data"] = ["/CLEO_2008_I787608/d06-x01-y01",
+ "/CLEO_2008_I787608/d06-x01-y02",
+ "/CLEO_2008_I787608/d06-x01-y03",
+ "/CLEO_2008_I787608/d06-x01-y04",
+ "/CLEO_2008_I787608/d06-x01-y05",]
# psi(3770)
analyses["HadronDecays"][30443] = { "Modes" : { "$\\psi(3770)\\to J/\\psi\\pi^0\\pi^0$" : {},
"$\\psi(3770)\\to J/\\psi\\pi^+\\pi^-$" : {},}}
analyses["HadronDecays"][30443]["Modes"]["$\\psi(3770)\\to J/\\psi\\pi^0\\pi^0$"]["MC" ] = ["/MC_Onium_PiPi_Decay/h_30443_443_mpi0pi0","/MC_Onium_PiPi_Decay/h_30443_443_hpi0pi0"]
analyses["HadronDecays"][30443]["Modes"]["$\\psi(3770)\\to J/\\psi\\pi^+\\pi^-$"]["MC" ] = ["/MC_Onium_PiPi_Decay/h_30443_443_hpippim","/MC_Onium_PiPi_Decay/h_30443_443_mpippim"]
# psi(2S)
analyses["HadronDecays"][100443] = { "Modes" : { "$\\psi(2S)\\to p\\bar{p}$" : {},
"$\\psi(2S)\\to n\\bar{n}$" : {},
"$\\psi(2S)\\to \\Sigma^{*-}\\bar\\Sigma^{*+}$" : {},
"$\\psi(2S)\\to \\Sigma^{*0}\\bar\\Sigma^{*0}$" : {},
"$\\psi(2S)\\to \\Sigma^{*+}\\bar\\Sigma^{*-}$" : {},
"$\\psi(2S)\\to \\Xi^{-}\\bar\\Xi^{+}$" : {},
"$\\psi(2S)\\to \\Xi^{*-}\\bar\\Xi^{*+}$" : {},
+ "$\\psi(2S)\\to \\Xi^{*0}\\bar\\Xi^{*0}$" : {},
"$\\psi(2S)\\to \\Xi^{0}\\bar\\Xi^{0}$" : {},
"$\\psi(2S)\\to \\Lambda^{0}\\bar\\Lambda^{0}$" : {},
"$\\psi(2S)\\to \\Sigma^{0}\\bar\\Sigma^{0}$" : {},
"$\\psi(2S)\\to J/\\psi\\pi^+\\pi^-$" : {},
- "$\\psi(2S)\\to J/\\psi\\pi^0\\pi^0$" : {},}}
+ "$\\psi(2S)\\to J/\\psi\\pi^0\\pi^0$" : {},
+ "$\\psi(2S)\\to \\Sigma^{+}\\bar\\Sigma^{-}$" : {},
+ "$\\psi(2S)\\to \\pi^+\\pi^-\\pi^0$" : {},
+ "$\\psi(2S)\\to K^+K^-\\pi^0$" : {},
+ "$\\psi(2S)\\to K^+K^-\\eta$" : {},
+ "$\\psi(2S)\\to p\\bar{p}\\pi^0$" : {},
+ "$\\psi(2S)\\to p\\bar{p}\\eta$" : {},
+ "$\\psi(2S)\\to p\\bar{p}\\phi$" : {},
+ "$\\psi(2S)\\to \\pi^+\\pi^-\\eta^\\prime$" : {},
+ "$\\psi(2S)\\to p\\bar{p}\\eta^\\prime$" : {},
+ "$\\psi(2S)\\to \\omega K^0_SK^0_S$" : {},
+ "$\\psi(2S)\\to \\Lambda\\bar\\Lambda\\eta$" : {},
+ "$\\psi(2S)\\to \\Lambda\\bar\\Lambda\\omega$" : {},
+ "$\\psi(2S)\\to n\\bar{p}\\pi^+$" : {},
+}}
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to p\\bar{p}$" ]["data"] = ["/BESIII_2018_I1658762/d01-x01-y01"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to p\\bar{p}$" ]["MC"] = ["/BESIII_2018_I1658762/ctheta_p"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to n\\bar{n}$" ]["data"] = ["/BESIII_2018_I1658762/d01-x01-y02"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to n\\bar{n}$" ]["MC"] = ["/BESIII_2018_I1658762/ctheta_n"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Sigma^{*-}\\bar\\Sigma^{*+}$"]["data"] = ["/BESIII_2016_I1422780/d02-x01-y05","/BESIII_2016_I1422780/d01-x01-y03"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Sigma^{*0}\\bar\\Sigma^{*0}$"]["data"] = ["/BESIII_2017_I1506414/d01-x01-y03","/BESIII_2017_I1506414/d02-x03-y01"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Sigma^{*+}\\bar\\Sigma^{*-}$"]["data"] = ["/BESIII_2016_I1422780/d02-x01-y06","/BESIII_2016_I1422780/d01-x01-y03"]
-analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Xi^{-}\\bar\\Xi^{+}$" ]["data"] = ["/BESIII_2016_I1422780/d02-x01-y04","/BESIII_2016_I1422780/d01-x01-y03"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Xi^{-}\\bar\\Xi^{+}$" ]["data"] = ["/BESIII_2016_I1422780/d02-x01-y04","/BESIII_2016_I1422780/d01-x01-y03",
+ "/BESIII_2022_I2099144/d02-x01-y01",
+ "/BESIII_2022_I2099144/d02-x01-y02"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Xi^{-}\\bar\\Xi^{+}$" ]["MC" ] = ["/BESIII_2022_I2099144/T1",
+ "/BESIII_2022_I2099144/T2",
+ "/BESIII_2022_I2099144/T3",
+ "/BESIII_2022_I2099144/T4",
+ "/BESIII_2022_I2099144/T5",
+ "/BESIII_2022_I2099144/cTheta",]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Xi^{0}\\bar\\Xi^{0}$" ]["data"] = ["/BESIII_2017_I1506414/d01-x01-y04","/BESIII_2017_I1506414/d02-x04-y01"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Lambda^{0}\\bar\\Lambda^{0}$"]["data"] = ["/BESIII_2017_I1510563/d01-x01-y02","/BESIII_2017_I1510563/d02-x03-y01"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Sigma^{0}\\bar\\Sigma^{0}$" ]["data"] = ["/BESIII_2017_I1510563/d01-x01-y04","/BESIII_2017_I1510563/d02-x04-y01"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Xi^{*-}\\bar\\Xi^{*+}$" ]["data"] = ["/BESIII_2019_I1747092/d01-x01-y01","/BESIII_2019_I1747092/d01-x01-y02",
"/BESIII_2019_I1747092/d02-x01-y01"]
-
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Xi^{*0}\\bar\\Xi^{*0}$" ]["data"] = ["/BESIII_2021_I1921775/d01-x01-y01",
+ "/BESIII_2021_I1921775/d01-x01-y02",
+ "/BESIII_2021_I1921775/d02-x01-y01"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to J/\\psi\\pi^+\\pi^-$"]["data"] = ["/MARKII_1979_I144382/d01-x01-y01","/BES_1999_I507637/d01-x01-y01",
"/BES_1999_I507637/d01-x01-y02","/BES_1999_I507637/d01-x01-y03","/BES_1999_I507637/d01-x01-y04"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to J/\\psi\\pi^0\\pi^0$"]["MC" ] = ["/MC_Onium_PiPi_Decay/h_100443_443_hpi0pi0",
"/MC_Onium_PiPi_Decay/h_100443_443_mpi0pi0"]
analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to J/\\psi\\pi^+\\pi^-$"]["MC" ] = ["/MC_Onium_PiPi_Decay/h_100443_443_hpippim",
"/MC_Onium_PiPi_Decay/h_100443_443_mpippim"]
-
-
-
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Sigma^{+}\\bar\\Sigma^{-}$"]["data"]=["/BESIII_2020_I1791570/d03-x01-y02",
+ "/BESIII_2020_I1791570/d04-x01-y02"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\pi^+\\pi^-\\pi^0$"]["data"] = ["/BESIII_2012_I1088606/d01-x01-y02",
+ "/BES_2005_I689969/d01-x01-y01"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\pi^+\\pi^-\\pi^0$"]["MC" ] = ["/BESIII_2012_I1088606/dalitz_psi2S",
+ "/BES_2005_I689969/dalitz"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to K^+K^-\\pi^0$" ]["data"] = ["/BESIII_2012_I1127328/d01-x01-y01",
+ "/BESIII_2012_I1127328/d01-x01-y02"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to K^+K^-\\pi^0$" ]["MC" ] = ["/BESIII_2012_I1127328/dalitz"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to p\\bar{p}\\pi^0$" ]["data"] = ["/BESIII_2013_I1120737/d01-x01-y01"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to p\\bar{p}\\pi^0$" ]["MC" ] = ["/BESIII_2013_I1120737/dalitz"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to p\\bar{p}\\eta$" ]["data"] = ["/BESIII_2013_I1227512/d01-x01-y01",
+ "/BESIII_2013_I1227512/d01-x01-y02",
+ "/BESIII_2013_I1227512/d01-x01-y03"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to p\\bar{p}\\eta$" ]["MC" ] = ["/BESIII_2013_I1227512/dalitz"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to p\\bar{p}\\phi$" ]["data"] = ["/BESIII_2019_I1722111/d01-x01-y01",
+ "/BESIII_2019_I1722111/d01-x01-y02",
+ "/BESIII_2019_I1722111/d01-x01-y03"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to p\\bar{p}\\phi$" ]["MC" ] = ["/BESIII_2019_I1722111/dalitz"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\pi^+\\pi^-\\eta^\\prime$" ]["data"] = ["/BESIII_2017_I1621266/d01-x01-y03",
+ "/BESIII_2017_I1621266/d01-x01-y04"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\pi^+\\pi^-\\eta^\\prime$" ]["MC" ] = ["/BESIII_2017_I1621266/dalitz_psi2S"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to p\\bar{p}\\eta^\\prime$" ]["data"]=["/BESIII_2019_I1709205/d01-x01-y01",
+ "/BESIII_2019_I1709205/d01-x01-y02",
+ "/BESIII_2019_I1709205/d01-x01-y03",
+ "/BESIII_2019_I1709205/d01-x01-y04",
+ "/BESIII_2019_I1709205/d01-x01-y05",
+ "/BESIII_2019_I1709205/d01-x01-y06",]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to p\\bar{p}\\eta^\\prime$" ]["MC" ]=["/BESIII_2019_I1709205/dalitz_1"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to K^+K^-\\eta$" ]["data"]=["/BESIII_2020_I1771616/d01-x01-y01",
+ "/BESIII_2020_I1771616/d01-x01-y02",
+ "/BESIII_2020_I1771616/d01-x01-y03"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to K^+K^-\\eta$" ]["MC" ]=["/BESIII_2020_I1771616/dalitz"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\omega K^0_SK^0_S$" ]["data"]=["/BESIII_2021_I1921801/d01-x01-y01",
+ "/BESIII_2021_I1921801/d01-x01-y02",
+ "/BESIII_2021_I1921801/d01-x01-y03"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\omega K^0_SK^0_S$" ]["MC" ]=["/BESIII_2021_I1921801/dalitz"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Lambda\\bar\\Lambda\\eta$"]["data"]=["/BESIII_2022_I2128095/d01-x01-y01",
+ "/BESIII_2022_I2128095/d01-x01-y02",
+ "/BESIII_2022_I2128095/d01-x01-y03"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Lambda\\bar\\Lambda\\eta$"]["MC" ]=["/BESIII_2022_I2128095/dalitz"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Lambda\\bar\\Lambda\\omega$"]["data"]=["/BESIII_2022_I2122392/d01-x01-y01",
+ "/BESIII_2022_I2122392/d01-x01-y02"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to \\Lambda\\bar\\Lambda\\omega$"]["MC" ]=["/BESIII_2022_I2122392/dalitz"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to n\\bar{p}\\pi^+$" ]["data"]=["/BESII_2006_I716589/d01-x01-y01",
+ "/BESII_2006_I716589/d01-x01-y02"]
+analyses["HadronDecays"][100443]["Modes"]["$\\psi(2S)\\to n\\bar{p}\\pi^+$" ]["MC" ]=["/BESII_2006_I716589/dalitz_1",
+ "/BESII_2006_I716589/dalitz_2"]
# bottomonium
# upsilon(1s)
analyses["HadronDecays"][553] = { "Mult" : {}, "Spectrum" : {}, "Shapes" : [] }
analyses["HadronDecays"][553]["Shapes"]=["/ARGUS_1986_I227324/d01-x01-y01","/ARGUS_1986_I227324/d02-x01-y01","/LENA_1981_I164397/d04-x01-y03"]
analyses["HadronDecays"][553]["Mult"][3122 ] = ["/ARGUS_1988_I251097/d01-x01-y01","/CLEO_1985_I205668/d17-x01-y01"]
analyses["HadronDecays"][553]["Mult"][3312 ] = ["/ARGUS_1988_I251097/d01-x01-y02","/CLEO_1985_I205668/d18-x01-y01"]
analyses["HadronDecays"][553]["Mult"][3212 ] = ["/ARGUS_1988_I251097/d01-x01-y03"]
analyses["HadronDecays"][553]["Mult"][3114 ] = ["/ARGUS_1988_I251097/d01-x01-y04"]
analyses["HadronDecays"][553]["Mult"][3224 ] = ["/ARGUS_1988_I251097/d01-x01-y05"]
analyses["HadronDecays"][553]["Mult"][3324 ] = ["/ARGUS_1988_I251097/d01-x01-y06"]
analyses["HadronDecays"][553]["Mult"][3334 ] = ["/ARGUS_1988_I251097/d01-x01-y07"]
analyses["HadronDecays"][553]["Mult"][333 ] = ["/ARGUS_1989_I262551/d03-x01-y01","/ARGUS_1993_S2789213/d02-x01-y05",
"/CLEO_1985_I205668/d22-x01-y01"]
analyses["HadronDecays"][553]["Mult"][211 ] = ["/ARGUS_1989_I276860/d01-x01-y01","/ARGUS_1989_I276860/d01-x01-y02",
"/CLEO_1985_I205668/d12-x01-y01"]
analyses["HadronDecays"][553]["Mult"][311 ] = ["/ARGUS_1989_I276860/d02-x01-y01","/CLEO_1985_I205668/d16-x01-y01"]
analyses["HadronDecays"][553]["Mult"][321 ] = ["/ARGUS_1989_I276860/d03-x01-y01","/CLEO_1985_I205668/d02-x01-y02",
"/CLEO_1985_I205668/d13-x01-y01"]
analyses["HadronDecays"][553]["Mult"][2212 ] = ["/ARGUS_1989_I276860/d04-x01-y01","/ARGUS_1989_I276860/d04-x01-y02",
"/CLEO_1985_I205668/d14-x01-y01"]
analyses["HadronDecays"][553]["Mult"][111 ] = ["/ARGUS_1990_I278933/d01-x01-y02","/CLEO_1985_I205668/d15-x01-y01",
"/CRYSTAL_BALL_1991_I297905/d02-x01-y01"]
analyses["HadronDecays"][553]["Mult"][221 ] = ["/ARGUS_1990_I278933/d02-x01-y02",
"/CRYSTAL_BALL_1991_I297905/d02-x01-y02"]
analyses["HadronDecays"][553]["Mult"][331 ] = ["/ARGUS_1993_S2669951/d01-x01-y01","/ARGUS_1993_S2669951/d01-x01-y02",
"/CLEOII_2002_I601701/d02-x01-y03","/CLEOIII_2006_I728679/d02-x01-y01"]
analyses["HadronDecays"][553]["Mult"][113 ] = ["/ARGUS_1993_S2789213/d02-x01-y02","/CLEO_1985_I205668/d19-x01-y01"]
analyses["HadronDecays"][553]["Mult"][223 ] = ["/ARGUS_1993_S2789213/d02-x01-y01"]
analyses["HadronDecays"][553]["Mult"][313 ] = ["/ARGUS_1993_S2789213/d02-x01-y03","/CLEO_1985_I205668/d21-x01-y01"]
analyses["HadronDecays"][553]["Mult"][323 ] = ["/ARGUS_1993_S2789213/d02-x01-y04","/CLEO_1985_I205668/d20-x01-y01"]
analyses["HadronDecays"][553]["Mult"][9010221] = ["/ARGUS_1993_S2669951/d05-x01-y01"]
analyses["HadronDecays"][553]["Mult"][2224 ] = ["/ARGUS_1989_I278932/d01-x01-y02"]
analyses["HadronDecays"][553]["Mult"][3124 ] = ["/ARGUS_1989_I262415/d01-x01-y01",
"/ARGUS_1989_I262415/d01-x02-y01"]
analyses["HadronDecays"][553]["Mult"][225 ] = ["/CLEO_1985_I205668/d23-x01-y01"]
+analyses["HadronDecays"][553]["Mult"][1000010020] = ["/BABAR_2014_I1286317/d03-x01-y01"]
analyses["HadronDecays"][553]["Spectrum"][3122] = ["/ARGUS_1988_I251097/d03-x01-y01","/CLEO_1985_I205668/d06-x01-y02"]
analyses["HadronDecays"][553]["Spectrum"][3312] = ["/ARGUS_1988_I251097/d07-x01-y01","/CLEO_1985_I205668/d07-x01-y02"]
analyses["HadronDecays"][553]["Spectrum"][3124] = ["/ARGUS_1989_I262415/d03-x01-y01"]
analyses["HadronDecays"][553]["Spectrum"][333 ] = ["/ARGUS_1989_I262551/d02-x01-y01","/CLEO_1985_I205668/d11-x01-y02"]
analyses["HadronDecays"][553]["Spectrum"][211 ] = ["/ARGUS_1989_I276860/d05-x01-y01","/ARGUS_1989_I276860/d09-x01-y01",
"/CLEO_1985_I205668/d01-x01-y02"]
analyses["HadronDecays"][553]["Spectrum"][321 ] = ["/ARGUS_1989_I276860/d06-x01-y01","/ARGUS_1989_I276860/d10-x01-y01"]
analyses["HadronDecays"][553]["Spectrum"][311 ] = ["/ARGUS_1989_I276860/d07-x01-y01","/ARGUS_1989_I276860/d11-x01-y01",
"/PLUTO_1981_I165122/d06-x01-y01","/CLEO_1985_I205668/d05-x01-y02"]
analyses["HadronDecays"][553]["Spectrum"][2212] = ["/ARGUS_1989_I276860/d08-x01-y01","/ARGUS_1989_I276860/d12-x01-y01",
"/CLEO_1985_I205668/d03-x01-y02"]
analyses["HadronDecays"][553]["Spectrum"][2224] = ["/ARGUS_1989_I278932/d03-x01-y01"]
analyses["HadronDecays"][553]["Spectrum"][22 ] = ["/CRYSTAL_BALL_1991_I315873/d02-x01-y01",
"/CRYSTAL_BALL_1991_I315873/d02-x01-y02","/ARGUS_1987_I248655/d02-x01-y01"]
analyses["HadronDecays"][553]["Spectrum"][111 ] = ["/ARGUS_1990_I278933/d04-x01-y01","/CLEO_1985_I205668/d04-x01-y02",
"/CRYSTAL_BALL_1991_I297905/d04-x01-y01"]
analyses["HadronDecays"][553]["Spectrum"][221 ] = ["/ARGUS_1990_I278933/d06-x01-y01","/CRYSTAL_BALL_1991_I297905/d06-x01-y01"]
analyses["HadronDecays"][553]["Spectrum"][9010221] = ["/ARGUS_1993_S2669951/d03-x01-y01"]
analyses["HadronDecays"][553]["Spectrum"][323 ] = ["/ARGUS_1993_S2789213/d05-x01-y01","/CLEO_1985_I205668/d09-x01-y02"]
analyses["HadronDecays"][553]["Spectrum"][313 ] = ["/ARGUS_1993_S2789213/d08-x01-y01","/CLEO_1985_I205668/d10-x01-y02"]
analyses["HadronDecays"][553]["Spectrum"][113 ] = ["/ARGUS_1993_S2789213/d11-x01-y01","/CLEO_1985_I205668/d08-x01-y02"]
analyses["HadronDecays"][553]["Spectrum"][223 ] = ["/ARGUS_1993_S2789213/d14-x01-y01"]
analyses["HadronDecays"][553]["Spectrum"][331 ] = ["/CLEOII_2002_I601701/d01-x01-y03","/CLEOIII_2006_I728679/d01-x01-y01"]
analyses["HadronDecays"][553]["Spectrum"][413 ] = ["/BABAR_2009_I836615/d01-x01-y01"]
+analyses["HadronDecays"][553]["Spectrum"][1000010020] = ["/ARGUS_1990_I283027/d01-x01-y01","/BABAR_2014_I1286317/d06-x03-y01"]
# upsion(2s)
analyses["HadronDecays"][100553] = { "Mult" : {}, "Spectrum" : {}, "Shapes" : [], "Other" : [],
"Modes" : { "$\\Upsilon(2S)\\to J/\\psi\\pi^0\\pi^0$" : {},
"$\\Upsilon(2S)\\to J/\\psi\\pi^+\\pi^-$" : {},
"$\\Upsilon(2S)\\to \\Upsilon(1S))\\pi^0\\pi^0$" : {},
"$\\Upsilon(2S)\\to \\Upsilon(1S)\\pi^+\\pi^-$" : {},}}
analyses["HadronDecays"][100553]["Shapes"] = ["/LENA_1981_I164397/d04-x01-y04"]
analyses["HadronDecays"][100553]["Other"] = ["/CLEOII_2002_I606309/d01-x01-y01","/CLEOII_2002_I606309/d01-x01-y02",
"/CLEOII_2002_I606309/d02-x01-y01","/CLEOII_2002_I606309/d04-x01-y01","/CLEOII_2002_I606309/d04-x01-y02"]
analyses["HadronDecays"][100553]["Mult"][111]= ["/ARGUS_1990_I278933/d01-x01-y03"]
analyses["HadronDecays"][100553]["Mult"][221]= ["/ARGUS_1990_I278933/d02-x01-y03"]
analyses["HadronDecays"][100553]["Mult"][333]= ["/ARGUS_1989_I262551/d04-x01-y01"]
+analyses["HadronDecays"][100553]["Mult"][1000010020] = ["/BABAR_2014_I1286317/d02-x01-y01"]
analyses["HadronDecays"][100553]["Spectrum"][3122] = ["/ARGUS_1988_I251097/d04-x01-y01"]
analyses["HadronDecays"][100553]["Spectrum"][3312] = ["/ARGUS_1988_I251097/d08-x01-y01"]
analyses["HadronDecays"][100553]["Spectrum"][333 ] = ["/ARGUS_1989_I262551/d02-x01-y02"]
analyses["HadronDecays"][100553]["Spectrum"][111 ] = ["/ARGUS_1990_I278933/d04-x01-y02"]
analyses["HadronDecays"][100553]["Spectrum"][221 ] = ["/ARGUS_1990_I278933/d06-x01-y02"]
analyses["HadronDecays"][100553]["Spectrum"][9010221] = ["/ARGUS_1993_S2669951/d04-x01-y01"]
+analyses["HadronDecays"][100553]["Spectrum"][1000010020] = ["/BABAR_2014_I1286317/d06-x02-y01"]
analyses["HadronDecays"][100553]["Modes"]["$\\Upsilon(2S)\\to \\Upsilon(1S))\\pi^0\\pi^0$"]["data"] = ["/CLEOII_1998_I467642/d03-x01-y01"]
analyses["HadronDecays"][100553]["Modes"]["$\\Upsilon(2S)\\to \\Upsilon(1S))\\pi^0\\pi^0$"]["MC"] = ["/MC_Onium_PiPi_Decay/h_100553_553_mpi0pi0",
"/MC_Onium_PiPi_Decay/h_100553_553_hpi0pi0"]
analyses["HadronDecays"][100553]["Modes"]["$\\Upsilon(2S)\\to \\Upsilon(1S)\\pi^+\\pi^-$" ]["data"] = ["/CUSB_1984_I199809/d01-x01-y01",
"/CLEOII_1998_I467642/d01-x01-y01","/CLEOII_1998_I467642/d02-x01-y01",
"/CLEOII_1998_I467642/d04-x01-y01","/CLEOII_1998_I467642/d04-x01-y02",
"/CLEOII_1998_I467642/d05-x01-y01","/CLEOII_1998_I467642/d05-x01-y02",
"/CLEOII_1998_I467642/d06-x01-y01","/CLEOII_1998_I467642/d06-x01-y02",
"/CLEOII_1994_I356001/d04-x01-y01","/CLEOII_1994_I356001/d04-x01-y02",
"/BELLE_2017_I1610301/d01-x01-y01","/BELLE_2017_I1610301/d02-x01-y01"]
analyses["HadronDecays"][100553]["Modes"]["$\\Upsilon(2S)\\to \\Upsilon(1S)\\pi^+\\pi^-$" ]["MC" ] = ["/MC_Onium_PiPi_Decay/h_100553_553_mpippim",
"/MC_Onium_PiPi_Decay/h_100553_553_hpippim"]
# Upsilon 3S
-analyses["HadronDecays"][200553] = { "Modes" : {"$\\Upsilon(3S)\\to\\Upsilon(1S)\\pi^0\\pi^0$" : {},
+analyses["HadronDecays"][200553] = {"Spectrum" : {}, "Mult" : {},
+ "Modes" : {"$\\Upsilon(3S)\\to\\Upsilon(1S)\\pi^0\\pi^0$" : {},
"$\\Upsilon(3S)\\to\\Upsilon(1S)\\pi^+\\pi^-$" : {},
"$\\Upsilon(3S)\\to\\Upsilon(2S)\\pi^0\\pi^0$" : {},
"$\\Upsilon(3S)\\to\\Upsilon(2S)\\pi^+\\pi^-$" : {}}}
analyses["HadronDecays"][200553]["Modes"]["$\\Upsilon(3S)\\to\\Upsilon(1S)\\pi^0\\pi^0$"]["data"]=["/CLEOII_1994_I356001/d01-x01-y01"]
analyses["HadronDecays"][200553]["Modes"]["$\\Upsilon(3S)\\to\\Upsilon(1S)\\pi^+\\pi^-$"]["data"]=["/CLEOII_1994_I356001/d02-x01-y01",
"/CLEOII_1994_I356001/d02-x01-y02",
"/BELLE_2017_I1610301/d01-x01-y02","/BELLE_2017_I1610301/d02-x01-y02"]
analyses["HadronDecays"][200553]["Modes"]["$\\Upsilon(3S)\\to\\Upsilon(2S)\\pi^0\\pi^0$"]["data"]=["/CLEOII_1994_I356001/d01-x01-y02"]
analyses["HadronDecays"][200553]["Modes"]["$\\Upsilon(3S)\\to\\Upsilon(2S)\\pi^+\\pi^-$"]["data"]=["/CLEOII_1994_I356001/d03-x01-y01",
"/CLEOII_1994_I356001/d03-x01-y02"]
analyses["HadronDecays"][200553]["Modes"]["$\\Upsilon(3S)\\to\\Upsilon(1S)\\pi^0\\pi^0$"]["MC"]=["/MC_Onium_PiPi_Decay/h_200553_553_hpi0pi0",
"/MC_Onium_PiPi_Decay/h_200553_553_mpi0pi0"]
analyses["HadronDecays"][200553]["Modes"]["$\\Upsilon(3S)\\to\\Upsilon(1S)\\pi^+\\pi^-$"]["MC"]=["/MC_Onium_PiPi_Decay/h_200553_553_hpippim",
"/MC_Onium_PiPi_Decay/h_200553_553_mpippim"]
analyses["HadronDecays"][200553]["Modes"]["$\\Upsilon(3S)\\to\\Upsilon(2S)\\pi^0\\pi^0$"]["MC"]=["/MC_Onium_PiPi_Decay/h_200553_100553_hpi0pi0",
"/MC_Onium_PiPi_Decay/h_200553_100553_mpi0pi0"]
analyses["HadronDecays"][200553]["Modes"]["$\\Upsilon(3S)\\to\\Upsilon(2S)\\pi^+\\pi^-$"]["MC"]=["/MC_Onium_PiPi_Decay/h_200553_100553_hpippim",
"/MC_Onium_PiPi_Decay/h_200553_100553_mpippim"]
+analyses["HadronDecays"][200553]["Spectrum"][1000010020] = ["/BABAR_2014_I1286317/d06-x01-y01"]
+analyses["HadronDecays"][200553]["Mult"][1000010020] = ["/BABAR_2014_I1286317/d01-x01-y01"]
# upsilon(4s)
analyses["HadronDecays"][300553] = { "Mult" : {}, "Spectrum" : {}, "DistChargedMult" : {},
"Modes" : {"$\\Upsilon(4S)\\to\\Upsilon(1S)\\pi^0\\pi^0$" : {},
"$\\Upsilon(4S)\\to\\Upsilon(1S)\\pi^+\\pi^-$" : {},
"$\\Upsilon(4S)\\to\\Upsilon(2S)\\pi^0\\pi^0$" : {},
"$\\Upsilon(4S)\\to\\Upsilon(2S)\\pi^+\\pi^-$" : {},
"$\\Upsilon(4S)\\to J/\\psi\\pi^0\\pi^0$" : {},
"$\\Upsilon(4S)\\to J/\\psi\\pi^+\\pi^-$" : {},}}
analyses["HadronDecays"][300553]["Modes"]["$\\Upsilon(4S)\\to\\Upsilon(1S)\\pi^0\\pi^0$"]["MC"]=["/MC_Onium_PiPi_Decay/h_300553_553_hpi0pi0",
"/MC_Onium_PiPi_Decay/h_300553_553_mpi0pi0"]
analyses["HadronDecays"][300553]["Modes"]["$\\Upsilon(4S)\\to\\Upsilon(1S)\\pi^+\\pi^-$"]["MC"]=["/MC_Onium_PiPi_Decay/h_300553_553_hpippim",
"/MC_Onium_PiPi_Decay/h_300553_553_mpippim"]
analyses["HadronDecays"][300553]["Modes"]["$\\Upsilon(4S)\\to\\Upsilon(1S)\\pi^+\\pi^-$"]["data"]=["/BELLE_2009_I810744/d01-x01-y01",
"/BABAR_2006_I714448/d01-x01-y01",
"/BELLE_2017_I1610301/d01-x01-y03","/BELLE_2017_I1610301/d02-x01-y03"]
analyses["HadronDecays"][300553]["Modes"]["$\\Upsilon(4S)\\to\\Upsilon(2S)\\pi^0\\pi^0$"]["MC"]=["/MC_Onium_PiPi_Decay/h_300553_100553_hpi0pi0",
"/MC_Onium_PiPi_Decay/h_300553_100553_mpi0pi0"]
analyses["HadronDecays"][300553]["Modes"]["$\\Upsilon(4S)\\to\\Upsilon(2S)\\pi^+\\pi^-$"]["data"]=["/BABAR_2006_I714448/d01-x01-y02",
"/BELLE_2017_I1610301/d01-x01-y04","/BELLE_2017_I1610301/d02-x01-y04"]
analyses["HadronDecays"][300553]["Modes"]["$\\Upsilon(4S)\\to\\Upsilon(2S)\\pi^+\\pi^-$"]["MC"]=["/MC_Onium_PiPi_Decay/h_300553_100553_hpippim",
"/MC_Onium_PiPi_Decay/h_300553_100553_mpippim"]
analyses["HadronDecays"][300553]["Modes"]["$\\Upsilon(4S)\\to J/\\psi\\pi^0\\pi^0$" ]["MC"]=["/MC_Onium_PiPi_Decay/h_300553_553_hpi0pi0",
"/MC_Onium_PiPi_Decay/h_300553_553_mpi0pi0"]
analyses["HadronDecays"][300553]["Modes"]["$\\Upsilon(4S)\\to J/\\psi\\pi^+\\pi^-$" ]["MC"]=["/MC_Onium_PiPi_Decay/h_300553_553_mpippim",
"/MC_Onium_PiPi_Decay/h_300553_553_hpippim"]
analyses["HadronDecays"][300553]["DistChargedMult"]["data"] = ["/ARGUS_1992_I319102/d03-x01-y01","/CLEOII_1999_I504672/d02-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 0] = ["/CLEOII_1999_I504672/d01-x01-y01","/CLEOII_1999_I504672/d01-x01-y02",
"/CLEOII_1999_I504672/d01-x01-y03","/ARGUS_1992_I319102/d05-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 211 ] = ["/ARGUS_1993_S2653028/d07-x01-y01","/ARGUS_1993_S2653028/d08-x01-y01",
"/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d87-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 321 ] = ["/ARGUS_1993_S2653028/d09-x01-y01",
"/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d60-x01-y01",
"/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d61-x01-y01",
"/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d62-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 2212] = ["/ARGUS_1993_S2653028/d10-x01-y01","/ARGUS_1993_S2653028/d11-x01-y01",
"/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d110-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 223 ] = ["/ARGUS_1993_S2789213/d03-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 113 ] = ["/ARGUS_1993_S2789213/d03-x01-y02",
"/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d90-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 313 ] = ["/ARGUS_1993_S2789213/d03-x01-y03",
"/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d65-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 323 ] = ["/ARGUS_1993_S2789213/d03-x01-y04",
"/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d64-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 333 ] = ["/ARGUS_1993_S2789213/d03-x01-y05","/BABAR_2004_I632399/d01-x01-y01",
"/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d92-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 111 ] = ["/BELLE_2001_S4598261/d02-x01-y01",
"/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d88-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 4222] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d104-x01-y01",
"/CLEOII_1994_I361356/d01-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 4112] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d106-x01-y01","/CLEOII_1994_I361356/d01-x01-y02"]
analyses["HadronDecays"][300553]["Mult"][ 4122] = ["/BABAR_2007_S6895344/d04-x01-y01","/BELLE_2005_I686014/d01-x01-y04",
"/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d96-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 3122] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d113-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 3312] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d116-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 411 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d29-x01-y01","/BELLE_2005_I686014/d01-x01-y02"]
analyses["HadronDecays"][300553]["Mult"][ 421 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d30-x01-y01","/BELLE_2005_I686014/d01-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 413 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d31-x01-y01","/BELLE_2005_I686014/d01-x01-y06",
"/BELLE_2005_I686014/d01-x01-y07"]
analyses["HadronDecays"][300553]["Mult"][ 423 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d32-x01-y01","/BELLE_2005_I686014/d01-x01-y05"]
analyses["HadronDecays"][300553]["Mult"][ 431 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d33-x01-y01","/BABAR_2002_I582184/d02-x01-y01",
"/BELLE_2005_I686014/d01-x01-y03"]
analyses["HadronDecays"][300553]["Mult"][ 433 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d34-x01-y01","/BABAR_2002_I582184/d02-x01-y02"]
analyses["HadronDecays"][300553]["Mult"][ 443 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d48-x01-y01",
"/BABAR_2003_I593379/d01-x01-y01","/BABAR_2003_I593379/d01-x01-y02"]
analyses["HadronDecays"][300553]["Mult"][100443 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d50-x01-y01",
"/BABAR_2003_I593379/d01-x01-y07"]
analyses["HadronDecays"][300553]["Mult"][ 20443 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d51-x01-y01",
"/BABAR_2003_I593379/d01-x01-y03","/BABAR_2003_I593379/d01-x01-y04"]
analyses["HadronDecays"][300553]["Mult"][ 445 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d53-x01-y01",
"/BABAR_2003_I593379/d01-x01-y05","/BABAR_2003_I593379/d01-x01-y06"]
analyses["HadronDecays"][300553]["Mult"][ 311 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d63-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 221 ] = ["/PDG_Upsilon_4S_HADRON_MULTIPLICITIES/d89-x01-y01"]
analyses["HadronDecays"][300553]["Mult"][ 4332 ] = ["/BABAR_2007_I746745/d02-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][111 ] = ["/BELLE_2001_S4598261/d01-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][211 ] = ["/ARGUS_1993_S2653028/d01-x01-y01","/ARGUS_1993_S2653028/d02-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][321 ] = ["/ARGUS_1993_S2653028/d03-x01-y01","/ARGUS_1993_S2653028/d06-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][2212 ] = ["/ARGUS_1993_S2653028/d04-x01-y01","/ARGUS_1993_S2653028/d05-x01-y01",
"/CLEO_1992_I315181/d01-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][113 ] = ["/ARGUS_1993_S2789213/d12-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][3122 ] = ["/CLEO_1992_I315181/d03-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][3312 ] = ["/CLEO_1992_I315181/d04-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][4122 ] = ["/BABAR_2007_S6895344/d03-x01-y01","/CLEO_1992_I315181/d02-x01-y01","/BELLE_2005_I686014/d04-x01-y04"]
analyses["HadronDecays"][300553]["Spectrum"][4132 ] = ["/BABAR_2005_S6181155/d01-x01-y01","/BABAR_2005_S6181155/d02-x01-y01",
"/CLEOII_1997_I442910/d01-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][323 ] = ["/ARGUS_1993_S2789213/d06-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][313 ] = ["/ARGUS_1993_S2789213/d09-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][443 ] = ["/BABAR_2003_I593379/d06-x01-y01","/BABAR_2003_I593379/d10-x01-y01","/CLEOII_2002_I606309/d03-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][20443 ] = ["/BABAR_2003_I593379/d07-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][445 ] = ["/BABAR_2003_I593379/d07-x01-y02"]
analyses["HadronDecays"][300553]["Spectrum"][100443] = ["/BABAR_2003_I593379/d08-x01-y01","/CLEOII_2002_I606309/d03-x01-y02"]
analyses["HadronDecays"][300553]["Spectrum"][431 ] = ["/CLEO_2005_I1649168/d01-x01-y07","/BABAR_2002_I582184/d05-x01-y01","/BELLE_2005_I686014/d04-x01-y03"]
analyses["HadronDecays"][300553]["Spectrum"][433 ] = ["/BABAR_2002_I582184/d05-x01-y02"]
analyses["HadronDecays"][300553]["Spectrum"][333 ] = ["/CLEO_2007_I728872/d01-x01-y05","/BABAR_2004_I632399/d02-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][4232 ] = ["/CLEOII_1997_I442910/d02-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][11] = ["/BABAR_2017_I1498564/d01-x01-y01","/BABAR_2017_I1498564/d01-x01-y02"]
analyses["HadronDecays"][300553]["Spectrum"][411] = ["/BELLE_2005_I686014/d04-x01-y02"]
analyses["HadronDecays"][300553]["Spectrum"][421] = ["/BELLE_2005_I686014/d04-x01-y01"]
analyses["HadronDecays"][300553]["Spectrum"][413] = ["/BELLE_2005_I686014/d04-x01-y06","/BELLE_2005_I686014/d04-x01-y07"]
analyses["HadronDecays"][300553]["Spectrum"][423] = ["/BELLE_2005_I686014/d04-x01-y05"]
# chi_b (2P)
analyses["HadronDecays"][110551] = { "Mult" : {},"DistChargedMult" : {},"Shapes" : []}
analyses["HadronDecays"][120553] = { "Mult" : {},"DistChargedMult" : {},"Shapes" : []}
analyses["HadronDecays"][100555] = { "Mult" : {},"DistChargedMult" : {},"Shapes" : []}
analyses["HadronDecays"][110551]["Mult"][0] = ["/CLEOII_1992_I32611/d01-x03-y01"]
analyses["HadronDecays"][120553]["Mult"][0] = ["/CLEOII_1992_I32611/d01-x02-y01"]
analyses["HadronDecays"][100555]["Mult"][0] = ["/CLEOII_1992_I32611/d01-x01-y01"]
analyses["HadronDecays"][110551]["DistChargedMult"]["data"] = ["/CLEOII_1992_I32611/d02-x01-y01"]
analyses["HadronDecays"][120553]["DistChargedMult"]["data"] = ["/CLEOII_1992_I32611/d02-x01-y02"]
analyses["HadronDecays"][100555]["DistChargedMult"]["data"] = ["/CLEOII_1992_I32611/d02-x01-y03"]
analyses["HadronDecays"][110551]["Shapes"] = ["/CLEOII_1992_I32611/d01-x03-y02","/CLEOII_1992_I32611/d03-x01-y01"]
analyses["HadronDecays"][120553]["Shapes"] = ["/CLEOII_1992_I32611/d01-x02-y02","/CLEOII_1992_I32611/d03-x01-y02"]
analyses["HadronDecays"][100555]["Shapes"] = ["/CLEOII_1992_I32611/d01-x01-y02","/CLEOII_1992_I32611/d03-x01-y03"]
# upsilon(5s)
analyses["HadronDecays"][9000553] = {"Spectrum" : {}}
analyses["HadronDecays"][9000553]["Spectrum"][431 ] = ["/CLEO_2005_I1649168/d01-x01-y08"]
analyses["HadronDecays"][9000553]["Spectrum"][333 ] = ["/CLEO_2007_I728872/d02-x01-y05" ]
+# B_c
+analyses["HadronDecays"][543] = { "Modes" : { "$B_c^+\\to J/\\psi \\pi^+$" : {},
+ "$B_c^+\\to J/\\psi \\pi^+\\pi^+\\pi^-$" : {},
+ "$B_c^+\\to J/\\psi K^+K^-\\pi^+$" : {},
+ "$B_c^+\\to J/\\psi K^+\\pi^+\\pi^-$" : {},
+ "$B_c^+\\to J/\\psi K^+K^+K^-$" : {},
+ "$B_c^+\\to J/\\psi 3\\pi^+2\\pi^-$" : {},
+ "$B_c^+\\to J/\\psi 4\\pi^+3\\pi^-$" : {},
+ "$B_c^+\\to J/\\psi K^+K^-\\pi^+\\pi^+\\pi^-$" : {},
+ "$B_c^+\\to \\psi(2S) \\pi^+\\pi^+\\pi^-$" : {},
+ "$B_c^+\\to \\psi(2S) p\\bar{p}\\pi^+$" : {},
+}}
+analyses["HadronDecays"][543]["Modes"]["$B_c^+\\to J/\\psi \\pi^+$" ]["data"] = ["/LHCB_2012_I1097092/d03-x01-y01"]
+analyses["HadronDecays"][543]["Modes"]["$B_c^+\\to J/\\psi \\pi^+\\pi^+\\pi^-$"]["data"] = ["/LHCB_2012_I1097092/d01-x01-y01",
+ "/LHCB_2012_I1097092/d02-x01-y01",
+ "/LHCB_2012_I1097092/d03-x01-y02",
+ "/LHCB_2022_I1960979/d01-x01-y01",
+ "/LHCB_2022_I1960979/d01-x01-y02"]
+analyses["HadronDecays"][543]["Modes"]["$B_c^+\\to J/\\psi K^+K^-\\pi^+$" ]["data"] = ["/LHCB_2022_I1960979/d02-x01-y01",
+ "/LHCB_2022_I1960979/d02-x01-y02"]
+analyses["HadronDecays"][543]["Modes"]["$B_c^+\\to J/\\psi K^+\\pi^+\\pi^-$" ]["data"] = ["/LHCB_2022_I1960979/d03-x01-y01",]
+analyses["HadronDecays"][543]["Modes"]["$B_c^+\\to J/\\psi K^+K^+K^-$" ]["data"] = ["/LHCB_2022_I1960979/d04-x01-y01"]
+analyses["HadronDecays"][543]["Modes"]["$B_c^+\\to J/\\psi 3\\pi^+2\\pi^-$" ]["data"] = ["/LHCB_2022_I2138845/d01-x01-y01",
+ "/LHCB_2022_I2138845/d02-x01-y01",
+ "/LHCB_2022_I2138845/d03-x01-y01"]
+analyses["HadronDecays"][543]["Modes"]["$B_c^+\\to J/\\psi 4\\pi^+3\\pi^-$" ]["data"] = ["/LHCB_2022_I2138845/d01-x01-y03"]
+analyses["HadronDecays"][543]["Modes"]["$B_c^+\\to J/\\psi K^+K^-\\pi^+\\pi^+\\pi^-$"]["data"] = ["/LHCB_2022_I2138845/d01-x01-y02",
+ "/LHCB_2022_I2138845/d04-x01-y01",
+ "/LHCB_2022_I2138845/d04-x01-y02"]
+analyses["HadronDecays"][543]["Modes"]["$B_c^+\\to \\psi(2S) \\pi^+\\pi^+\\pi^-$" ]["data"] = ["/LHCB_2022_I2138845/d02-x01-y02",
+ "/LHCB_2022_I2138845/d03-x01-y02"]
+analyses["HadronDecays"][543]["Modes"]["$B_c^+\\to \\psi(2S) p\\bar{p}\\pi^+$" ]["data"] = ["/LHCB_2014_I1309880/d01-x01-y01",
+ "/LHCB_2014_I1309880/d01-x01-y02",]
#
analyses["HadronDecays"][3312] = { "Modes" : { "$\\Xi^-\\to\\Lambda^0\\pi^-$" : {} } }
analyses["HadronDecays"][3312]["Modes"]["$\\Xi^-\\to\\Lambda^0\\pi^-$"]["data"] = ["/E756_2000_I530367/d01-x01-y01","/E756_2000_I530367/d01-x01-y02",
"/CLEOII_2000_I533575/d01-x01-y01","/CLEOII_2000_I533575/d01-x01-y02",
- "/CLEOII_2000_I533575/d02-x01-y01","/CLEOII_2000_I533575/d02-x01-y02"]
+ "/CLEOII_2000_I533575/d02-x01-y01","/CLEOII_2000_I533575/d02-x01-y02",
+ "/BESIII_2022_I2099144/d02-x01-y03","/BESIII_2022_I2099144/d02-x01-y04"]
analyses["HadronDecays"][3312]["Modes"]["$\\Xi^-\\to\\Lambda^0\\pi^-$"]["MC" ] = ["/E756_2000_I530367/cthetaP","/E756_2000_I530367/cthetaM"]
analyses["HadronDecays"][3322] = { "Modes" : { "$\\Xi^0\\to\\Lambda^0\\pi^0$" : {}, "$\\Xi^0\\to\\Sigma^0\\gamma$" : {},
"$\\Xi^0\\to\\Lambda^0\\gamma$" : {} } }
analyses["HadronDecays"][3322]["Modes"]["$\\Xi^0\\to\\Lambda^0\\pi^0$"]["data"] = ["/NA48_2010_I868871/d01-x01-y01"]
analyses["HadronDecays"][3322]["Modes"]["$\\Xi^0\\to\\Lambda^0\\pi^0$"]["MC" ] = ["/NA48_2010_I868871/ctheta_pi0"]
analyses["HadronDecays"][3322]["Modes"]["$\\Xi^0\\to\\Lambda^0\\gamma$"]["data"] = ["/NA48_2010_I868871/d02-x01-y01"]
analyses["HadronDecays"][3322]["Modes"]["$\\Xi^0\\to\\Lambda^0\\gamma$"]["MC" ] = ["/NA48_2010_I868871/ctheta_gamma"]
analyses["HadronDecays"][3322]["Modes"]["$\\Xi^0\\to\\Sigma^0\\gamma$"]["data"] = ["/NA48_2010_I868871/d03-x01-y01"]
analyses["HadronDecays"][3322]["Modes"]["$\\Xi^0\\to\\Sigma^0\\gamma$"]["MC" ] = ["/NA48_2010_I868871/ctheta_Sigma_0" ,"/NA48_2010_I868871/ctheta_Sigma_1" ,
"/NA48_2010_I868871/ctheta_Sigma_2" ,"/NA48_2010_I868871/ctheta_Sigma_3" ,
"/NA48_2010_I868871/ctheta_Sigma_4" ,"/NA48_2010_I868871/ctheta_Sigma_5" ,
"/NA48_2010_I868871/ctheta_Sigma_6" ,"/NA48_2010_I868871/ctheta_Sigma_7" ,
"/NA48_2010_I868871/ctheta_Sigma_8" ,"/NA48_2010_I868871/ctheta_Sigma_9" ,
"/NA48_2010_I868871/ctheta_Sigma_10","/NA48_2010_I868871/ctheta_Sigma_11",
"/NA48_2010_I868871/ctheta_Sigma_12","/NA48_2010_I868871/ctheta_Sigma_13",
"/NA48_2010_I868871/ctheta_Sigma_14","/NA48_2010_I868871/ctheta_Sigma_15",
"/NA48_2010_I868871/ctheta_Sigma_16","/NA48_2010_I868871/ctheta_Sigma_17",
"/NA48_2010_I868871/ctheta_Sigma_18","/NA48_2010_I868871/ctheta_Sigma_19"]
analyses["HadronDecays"][3334] = { "Modes" : { "$\\Omega^-\\to\\Lambda^0K^-$" : {},"$\\Omega^-\\to\\Xi^0\\pi^-$" : {},
"$\\Omega^-\\to\\Xi^-\\pi^0$" : {} } }
analyses["HadronDecays"][3334]["Modes"]["$\\Omega^-\\to\\Lambda^0K^-$"]["data"] = ["/HyperCP_2005_I677384/d01-x01-y01",
"/HyperCP_2005_I677384/d01-x01-y02",
"/HyperCP_2005_I677384/d01-x01-y03",
"/WA46_1984_I206647/d01-x01-y01"]
analyses["HadronDecays"][3334]["Modes"]["$\\Omega^-\\to\\Lambda^0K^-$"]["MC" ] = ["/HyperCP_2005_I677384/cthetaM",
"/HyperCP_2005_I677384/cthetaP",
"/HyperCP_2005_I677384/cthetaAll",
"/WA46_1984_I206647/cthetaLambda"]
analyses["HadronDecays"][3334]["Modes"]["$\\Omega^-\\to\\Xi^0\\pi^-$"]["data"]=["/WA46_1984_I206647/d01-x01-y02"]
analyses["HadronDecays"][3334]["Modes"]["$\\Omega^-\\to\\Xi^0\\pi^-$"]["MC" ]=["/WA46_1984_I206647/cthetaXi0"]
analyses["HadronDecays"][3334]["Modes"]["$\\Omega^-\\to\\Xi^-\\pi^0$"]["data"]=["/WA46_1984_I206647/d01-x01-y03"]
analyses["HadronDecays"][3334]["Modes"]["$\\Omega^-\\to\\Xi^-\\pi^0$"]["MC" ]=["/WA46_1984_I206647/cthetaXim"]
-
-
-analyses["HadronDecays"][4132] = { "Modes" : { "$\\Xi^0_c\\to\\Xi^-\\pi^+$" : {}, "$\\Xi^0_c\\to\\Omega^-K^+" : {} } }
-analyses["HadronDecays"][4132]["Modes"]["$\\Xi^0_c\\to\\Xi^-\\pi^+$"]["data"] = ["/CLEO_2000_I537236/d01-x01-y01"]
+# Xi_c0
+analyses["HadronDecays"][4132] = { "Modes" : { "$\\Xi^0_c\\to\\Xi^-\\pi^+$" : {},
+ "$\\Xi^0_c\\to\\Omega^-K^+$" : {},
+ "$\\Xi^0_c\\to\\Lambda^0\\bar{K}^{*0}$" : {},
+ "$\\Xi^0_c\\to\\Sigma^0\\bar{K}^{*0}$" : {},
+ "$\\Xi^0_c\\to\\Sigma^-\\bar{K}^{*+}$" : {},
+ "$\\Xi^0_c\\to pK^-K^-\\pi^+$" : {},
+ "$\\Xi^0_c\\to K^+K^-\\Xi^0$" : {},} }
+analyses["HadronDecays"][4132]["Modes"]["$\\Xi^0_c\\to\\Xi^-\\pi^+$"]["data"] = ["/CLEO_2000_I537236/d01-x01-y01",
+ "/BELLE_2021_I1851126/d01-x01-y01","/BELLE_2021_I1851126/d01-x01-y02",
+ "/BELLE_2021_I1851126/d02-x01-y01","/BELLE_2021_I1851126/d02-x01-y02",
+ "/BELLE_2021_I1851126/d02-x01-y03","/BELLE_2021_I1851126/d02-x01-y04"]
analyses["HadronDecays"][4132]["Modes"]["$\\Xi^0_c\\to\\Xi^-\\pi^+$"]["MC" ] = ["/CLEO_2000_I537236/ctheta"]
-analyses["HadronDecays"][4132]["Modes"]["$\\Xi^0_c\\to\\Omega^-K^+"]["data"] = ["/BABAR_2006_I719581/d01-x01-y01","/BABAR_2006_I719581/d02-x01-y01"]
-
-analyses["HadronDecays"][4122] = { "Modes" : { "$\\Lambda^+_c\\to\\Lambda^0\\pi^+$" : {}, "$\\Lambda^+_c\\to\\Sigma^+\\pi^0$" : {},
- "$\\Lambda^+_c\\to\\Lambda^0 e^+\\bar{\\nu}_e$" : {} } }
+analyses["HadronDecays"][4132]["Modes"]["$\\Xi^0_c\\to\\Omega^-K^+$"]["data"] = ["/BABAR_2006_I719581/d01-x01-y01","/BABAR_2006_I719581/d02-x01-y01"]
+analyses["HadronDecays"][4132]["Modes"]["$\\Xi^0_c\\to\\Lambda^0\\bar{K}^{*0}$"]["data"]=["/BELLE_2021_I1859517/d01-x01-y01","/BELLE_2021_I1859517/d04-x01-y01"]
+analyses["HadronDecays"][4132]["Modes"]["$\\Xi^0_c\\to\\Sigma^0\\bar{K}^{*0}$" ]["data"]=["/BELLE_2021_I1859517/d02-x01-y01","/BELLE_2021_I1859517/d04-x01-y02"]
+analyses["HadronDecays"][4132]["Modes"]["$\\Xi^0_c\\to\\Sigma^-\\bar{K}^{*+}$" ]["data"]=["/BELLE_2021_I1859517/d03-x01-y01","/BELLE_2021_I1859517/d04-x01-y03"]
+analyses["HadronDecays"][4132]["Modes"]["$\\Xi^0_c\\to pK^-K^-\\pi^+$"]["data"]=["/BELLE_2005_I660759/d01-x01-y01",
+ "/CLEOIII_2004_I627327/d01-x01-y01"]
+analyses["HadronDecays"][4132]["Modes"]["$\\Xi^0_c\\to K^+K^-\\Xi^0$"]["data"]=["/BELLE_2021_I1835729/d01-x01-y01",
+ "/BELLE_2021_I1835729/d01-x01-y02",
+ "/BELLE_2021_I1835729/d01-x01-y03"]
+analyses["HadronDecays"][4132]["Modes"]["$\\Xi^0_c\\to K^+K^-\\Xi^0$"]["MC" ]=["/BELLE_2021_I1835729/dalitz"]
+# Xi_c+
+analyses["HadronDecays"][4232] = { "Modes" : { "$\\Xi^+_c\\to\\Xi^-\\pi^+\\pi^+$" : {},
+ "$\\Xi^+_c\\to \\Sigma^+K^-\\pi^+$" : {}, } }
+analyses["HadronDecays"][4232]["Modes"]["$\\Xi^+_c\\to\\Xi^-\\pi^+\\pi^+$"]["data"] = ["/BELLE_2018_I1698390/d01-x01-y01",
+ "/FOCUS_2003_I618864/d02-x01-y01"]
+analyses["HadronDecays"][4232]["Modes"]["$\\Xi^+_c\\to \\Sigma^+K^-\\pi^+$"]["data"]=["/CLEOII_1996_I397787/d01-x01-y01",
+ "/FOCUS_2003_I618864/d01-x01-y01"]
+# Lambda_c
+analyses["HadronDecays"][4122] = { "Modes" : { "$\\Lambda^+_c\\to\\Lambda^0\\pi^+$" : {},
+ "$\\Lambda^+_c\\to\\Sigma^+\\pi^0$" : {},
+ "$\\Lambda^+_c\\to\\Sigma^+\\eta$" : {},
+ "$\\Lambda^+_c\\to\\Sigma^+\\eta^\\prime$" : {},
+ "$\\Lambda^+_c\\to\\Lambda^0K^+$" : {},
+ "$\\Lambda^+_c\\to\\Sigma^0\\pi^+$" : {},
+ "$\\Lambda^+_c\\to\\Sigma^0K^+$" : {},
+ "$\\Lambda^+_c\\to\\Lambda^0 e^+\\bar{\\nu}_e$" : {},
+ "$\\Lambda^+_c\\to\\Xi^*(1530)^0K^+$" : {},
+ "$\Lambda_c^+\\to\\eta\\Lambda\\pi^+$" : {},
+ "$\Lambda_c^+\\to pK^0_S\\eta" : {},
+}}
analyses["HadronDecays"][4122]["Modes"]["$\\Lambda^+_c\\to\\Lambda^0\\pi^+$"]["data"] = ["/FOCUS_2006_I693639/d01-x01-y01","/FOCUS_2006_I693639/d02-x01-y01",
"/FOCUS_2006_I693639/d03-x01-y01",
"/CLEO_1995_I392704/d01-x01-y01","/CLEO_1995_I392704/d03-x01-y01",
- "/ARGUS_1992_I319105/d02-x01-y01","/ARGUS_1992_I319105/d03-x01-y01"]
-analyses["HadronDecays"][4122]["Modes"]["$\\Lambda^+_c\\to\\Sigma^+\\pi^0$"]["data"] = ["/CLEO_1995_I392704/d02-x01-y01","/CLEO_1995_I392704/d04-x01-y01"]
+ "/ARGUS_1992_I319105/d02-x01-y01","/ARGUS_1992_I319105/d03-x01-y01",
+ "/BELLE_2022_I2138841/d01-x02-y01","/BELLE_2022_I2138841/d01-x02-y02",
+ "/BELLE_2022_I2138841/d02-x02-y01","/BELLE_2022_I2138841/d02-x02-y02",
+ "/BELLE_2022_I2138841/d02-x02-y03","/BELLE_2022_I2138841/d02-x02-y04",
+ "/BELLE_2022_I2138841/d03-x01-y02","/BELLE_2022_I2138841/d04-x01-y03",
+ "/BELLE_2022_I2138841/d04-x01-y04"]
+analyses["HadronDecays"][4122]["Modes"]["$\\Lambda^+_c\\to\\Sigma^+\\pi^0$"]["data"] = ["/CLEO_1995_I392704/d02-x01-y01","/CLEO_1995_I392704/d04-x01-y01",
+ "/BELLE_2022_I2140379/d01-x01-y01","/BELLE_2022_I2140379/d01-x01-y02",
+ "/BELLE_2022_I2140379/d02-x01-y01"]
analyses["HadronDecays"][4122]["Modes"]["$\\Lambda^+_c\\to\\Lambda^0 e^+\\bar{\\nu}_e$"]["data"] = ["/CLEOII_2005_I668268/d01-x01-y01","/CLEOII_1994_I371611/d01-x01-y01",
- "/CLEOII_1994_I371611/d02-x01-y01","/ARGUS_1994_I371613/d01-x01-y01"]
+ "/CLEOII_1994_I371611/d02-x01-y01","/ARGUS_1994_I371613/d01-x01-y01",
+ "/BESIII_2022_I2127373/d01-x01-y01",
+ "/BESIII_2022_I2127373/d01-x01-y02",
+ "/BESIII_2022_I2127373/d01-x01-y03",
+ "/BESIII_2022_I2127373/d01-x01-y04"]
+analyses["HadronDecays"][4122]["Modes"]["$\\Lambda^+_c\\to\\Xi^*(1530)^0K^+$"]["data"]=["/BABAR_2008_I781294/d01-x01-y01","/BABAR_2008_I781294/d02-x01-y01",
+ "/BABAR_2008_I781294/d02-x01-y02"]
+analyses["HadronDecays"][4122]["Modes"]["$\Lambda_c^+\\to\\eta\\Lambda\\pi^+$"]["data"] = ["/BELLE_2020_I1813380/d01-x01-y01",
+ "/BELLE_2020_I1813380/d01-x01-y02",
+ "/BESIII_2019_I1711896/d01-x01-y01"]
+analyses["HadronDecays"][4122]["Modes"]["$\Lambda_c^+\\to\\eta\\Lambda\\pi^+$"]["MC" ] = ["/BESIII_2019_I1711896/dalitz"]
+analyses["HadronDecays"][4122]["Modes"]["$\\Lambda^+_c\\to\\Lambda^0K^+$" ]["data"] = ["/BELLE_2022_I2138841/d01-x01-y01","/BELLE_2022_I2138841/d01-x01-y02",
+ "/BELLE_2022_I2138841/d02-x01-y02","/BELLE_2022_I2138841/d02-x01-y04",
+ "/BELLE_2022_I2138841/d03-x01-y01","/BELLE_2022_I2138841/d04-x01-y01",
+ "/BELLE_2022_I2138841/d04-x01-y02"]
+analyses["HadronDecays"][4122]["Modes"]["$\\Lambda^+_c\\to\\Sigma^0\\pi^+$" ]["data"] = ["/BELLE_2022_I2138841/d01-x04-y01","/BELLE_2022_I2138841/d01-x04-y02",
+ "/BELLE_2022_I2138841/d02-x04-y01","/BELLE_2022_I2138841/d02-x04-y02",
+ "/BELLE_2022_I2138841/d02-x04-y03","/BELLE_2022_I2138841/d02-x04-y04"]
+analyses["HadronDecays"][4122]["Modes"]["$\\Lambda^+_c\\to\\Sigma^0K^+$" ]["data"] = ["/BELLE_2022_I2138841/d01-x03-y01","/BELLE_2022_I2138841/d01-x03-y02",
+ "/BELLE_2022_I2138841/d02-x03-y01","/BELLE_2022_I2138841/d02-x03-y02",
+ "/BELLE_2022_I2138841/d02-x03-y03","/BELLE_2022_I2138841/d02-x03-y04"]
+analyses["HadronDecays"][4122]["Modes"]["$\\Lambda^+_c\\to\\Sigma^+\\eta$" ]["data"] = ["/BELLE_2022_I2140379/d01-x02-y01","/BELLE_2022_I2140379/d01-x02-y02",
+ "/BELLE_2022_I2140379/d02-x01-y02"]
+analyses["HadronDecays"][4122]["Modes"]["$\\Lambda^+_c\\to\\Sigma^+\\eta^\\prime$"]["data"] = ["/BELLE_2022_I2140379/d01-x03-y01","/BELLE_2022_I2140379/d01-x03-y02",
+ "/BELLE_2022_I2140379/d02-x01-y03"]
+analyses["HadronDecays"][4122]["Modes"]["$\Lambda_c^+\\to pK^0_S\\eta" ]["data"] = ["/BESIII_2021_I1837968/d01-x01-y01",
+ "/BESIII_2021_I1837968/d01-x01-y02",
+ "/BESIII_2021_I1837968/d01-x01-y03",]
+# Sigma_c++
analyses["HadronDecays"][4222] = { "Modes" : {"$\\Sigma^*\\to\\Lambda_c\\pi$" : {} } }
analyses["HadronDecays"][4222]["Modes"]["$\\Sigma^*\\to\\Lambda_c\\pi$"]["data"] = ["/CLEOII_1997_I424575/d02-x01-y01"]
+# Omega_c
+analyses["HadronDecays"][4332] = { "Modes" : { "$\Omega_c^0\\to\\Omega^-\\pi^+\\pi^0$" : {},
+ "$\Omega_c^0\\to\\Xi^-K^-\\pi^+\\pi^+$" : {},
+ "$\Omega_c^0\\to\\Xi^0K^-\\pi^+$" : {},} }
+analyses["HadronDecays"][4332]["Modes"]["$\Omega_c^0\\to\\Omega^-\\pi^+\\pi^0$"]["data"] = ["/BELLE_2018_I1641071/d01-x01-y01"]
+analyses["HadronDecays"][4332]["Modes"]["$\Omega_c^0\\to\\Xi^-K^-\\pi^+\\pi^+$"]["data"] = ["/BELLE_2018_I1641071/d01-x01-y02",
+ "/BELLE_2018_I1641071/d01-x01-y03"]
+analyses["HadronDecays"][4332]["Modes"]["$\Omega_c^0\\to\\Xi^0K^-\\pi^+$" ]["data"] = ["/BELLE_2018_I1641071/d01-x01-y04"]
+# lambda_b
+analyses["HadronDecays"][5122] = { "Modes" : { "$\\Lambda^0_b\\to\\Lambda^+_c\\mu^-\\bar\\nu_\\mu" : {} }}
+analyses["HadronDecays"][5122]["Modes"]["$\\Lambda^0_b\\to\\Lambda^+_c\\mu^-\\bar\\nu_\\mu"]["data"] = ["/LHCB_2017_I1621811/d01-x01-y01"]
+# lambda_b*
+analyses["HadronDecays"][101254] = { "Modes" : { "$\\Lambda_b(5920)^0\\to\\Lambda^0_b\\pi^+\\pi^-" : {} }}
+analyses["HadronDecays"][101254]["Modes"]["$\\Lambda_b(5920)^0\\to\\Lambda^0_b\\pi^+\\pi^-"]["data"] = ["/LHCB_2012_I1114753/d01-x01-y01"]
+
# charged multiplicity (total)
analyses["Charged"]["TotalChargedMult"][0][9.5 ] = ["/LENA_1981_I164397/d03-x01-y01"]
analyses["Charged"]["TotalChargedMult"][0][10.47] = ["/ARGUS_1992_I319102/d04-x01-y01"]
analyses["Charged"]["TotalChargedMult"][0][12.0 ] = ["/JADE_1983_I190818/d01-x01-y01"]
-analyses["Charged"]["TotalChargedMult"][0][14.0 ] = ["/TASSO_1989_I277658/d02-x01-y01"]
+analyses["Charged"]["TotalChargedMult"][0][14.0 ] = ["/TASSO_1989_I277658/d02-x01-y01","/TASSO_1984_I195333/d04-x01-y01"]
analyses["Charged"]["TotalChargedMult"][0][21.65] = ["/PLUTO_1980_I154270/d01-x01-y01"]
analyses["Charged"]["TotalChargedMult"][0][22.0 ] = ["/TASSO_1980_I143691/d01-x01-y01","/JADE_1979_I142874/d02-x01-y01"]
analyses["Charged"]["TotalChargedMult"][0][29.0 ] = ["/TPC_1987_I235694/d05-x01-y04","/HRS_1986_I18502/d03-x01-y01"]
analyses["Charged"]["TotalChargedMult"][0][50.0 ] = ["/AMY_1990_I295160/d02-x01-y01"]
analyses["Charged"]["TotalChargedMult"][0][55.7 ] = ["/AMY_1990_I295160/d02-x02-y01"]
analyses["Charged"]["TotalChargedMult"][0][57.8 ] = ["/TOPAZ_1997_I454183/d01-x01-y01"]
analyses["Charged"]["TotalChargedMult"][0][91.2 ] = ["/ALEPH_1991_S2435284/d02-x01-y01","/OPAL_1992_I321190/d05-x01-y01",
"/DELPHI_1991_I301657/d04-x01-y01","/ALEPH_2004_S5765862/d01-x01-y01",
"/DELPHI_1996_S3430090/d35-x01-y01","/DELPHI_1998_I473409/d01-x01-y01",
"/OPAL_1998_S3780481/d09-x01-y04","/ALEPH_1996_S3486095/d19-x01-y01"]
analyses["Charged"]["TotalChargedMult"][0][161.0] = ["/OPAL_1997_I440721/d02-x01-y01"]
analyses["Charged"]["TotalChargedMult"][0][172.0] = ["/OPAL_2000_I513476/d14-x01-y01"]
+analyses["Charged"]["TotalChargedMult"][0][183.0] = ["/DELPHI_2001_I526164/d01-x01-y01"]
# light quark events
analyses["Charged"]["TotalChargedMult"][1][29.0 ] = ["/TPC_1987_I235694/d04-x01-y04"]
analyses["Charged"]["TotalChargedMult"][1][58.0 ] = ["/VENUS_1998_I453613/d01-x01-y02"]
analyses["Charged"]["TotalChargedMult"][1][91.2 ] = ["/OPAL_2002_S5361494/d01-x01-y03","/OPAL_1998_S3780481/d09-x01-y01",
"/DELPHI_1998_I473409/d03-x01-y01","/SLD_2004_S5693039/d08-x02-y01",
"/SLD_1996_S3398250/d03-x01-y01","/DELPHI_1999_I448370/d09-x01-y02",
"/OPAL_2001_I536266/d01-x01-y01","/OPAL_2001_I536266/d01-x01-y02",
"/OPAL_2001_I536266/d01-x01-y03","/OPAL_2001_I536266/d02-x01-y01",
"/OPAL_2001_I536266/d02-x01-y02","/OPAL_2001_I536266/d02-x01-y03"]
analyses["Charged"]["TotalChargedMult"][1 ][195.0] = ["/DELPHI_2000_S4328825/d01-x01-y03"]
# charm events
analyses["Charged"]["TotalChargedMult"][4][29.0 ] = ["/TPC_1987_I235694/d03-x01-y04"]
analyses["Charged"]["TotalChargedMult"][4][91.2 ] = ["/OPAL_2002_S5361494/d01-x01-y02","/OPAL_1998_S3780481/d09-x01-y02",
"/SLD_2004_S5693039/d08-x02-y02","/SLD_1996_S3398250/d02-x01-y01"]
analyses["Charged"]["TotalChargedMult"][4 ][195.0] = ["/DELPHI_2000_S4328825/d01-x01-y02"]
# bottom events
analyses["Charged"]["TotalChargedMult"][5][29.0 ] = ["/TPC_1987_I235694/d02-x01-y04"]
analyses["Charged"]["TotalChargedMult"][5][58.0 ] = ["/VENUS_1998_I453613/d01-x01-y01"]
analyses["Charged"]["TotalChargedMult"][5][91.2 ] = ["/OPAL_2002_S5361494/d01-x01-y01","/OPAL_1998_S3780481/d09-x01-y03",
"/DELPHI_1998_I473409/d02-x01-y01","/SLD_2004_S5693039/d08-x02-y03",
"/SLD_1996_S3398250/d01-x01-y01","/DELPHI_1999_I448370/d09-x01-y01"]
analyses["Charged"]["TotalChargedMult"][5 ][195.0] = ["/DELPHI_2000_S4328825/d01-x01-y01"]
# difference charm-light
analyses["Charged"]["TotalChargedMult"][41][91.2 ] = ["/SLD_2004_S5693039/d08-x03-y02","/SLD_1996_S3398250/d04-x01-y01"]
# difference bottom-light
analyses["Charged"]["TotalChargedMult"][51][58.0 ] = ["/VENUS_1998_I453613/d01-x01-y03"]
analyses["Charged"]["TotalChargedMult"][51][91.2 ] = ["/OPAL_2002_S5361494/d01-x01-y04","/SLD_2004_S5693039/d08-x03-y03",
"/SLD_1996_S3398250/d05-x01-y01"]
analyses["Charged"]["TotalChargedMult"][51][195.0] = ["/DELPHI_2000_S4328825/d01-x01-y04"]
# with cuts
analyses["Charged"]["TotalChargedMult"]["C"][91.2] = ["\ALEPH_1996_S3486095/d20-x01-y01","\ALEPH_1996_S3486095/d21-x01-y01",
"\ALEPH_1996_S3486095/d22-x01-y01","\ALEPH_1996_S3486095/d23-x01-y01"]
# charged multiplicity (dist)
analyses["Charged"]["DistChargedMult"][0][10.47] = ["/ARGUS_1992_I319102/d02-x01-y01"]
-analyses["Charged"]["DistChargedMult"][0][14.0] = ["/TASSO_1989_I277658/d05-x01-y01"]
-analyses["Charged"]["DistChargedMult"][0][22.0] = ["/TASSO_1989_I277658/d05-x01-y02"]
+analyses["Charged"]["DistChargedMult"][0][14.0] = ["/TASSO_1989_I277658/d05-x01-y01","/TASSO_1984_I195333/d03-x01-y01"]
+analyses["Charged"]["DistChargedMult"][0][22.0] = ["/TASSO_1989_I277658/d05-x01-y02","/TASSO_1984_I195333/d03-x01-y02"]
analyses["Charged"]["DistChargedMult"][0][29.0] = ["/HRS_1986_I18502/d01-x01-y01"]
+analyses["Charged"]["DistChargedMult"][0][34.0] = ["/TASSO_1984_I195333/d03-x01-y03"]
analyses["Charged"]["DistChargedMult"][0][34.8] = ["/TASSO_1989_I277658/d05-x01-y03"]
analyses["Charged"]["DistChargedMult"][0][35.0] = ["/TASSO_1988_I263859/d06-x01-y01"]
analyses["Charged"]["DistChargedMult"][0][43.6] = ["/TASSO_1989_I277658/d05-x01-y04"]
analyses["Charged"]["DistChargedMult"][0][50.0] = ["/AMY_1990_I295160/d01-x01-y01"]
analyses["Charged"]["DistChargedMult"][0][52.0] = ["/AMY_1990_I295160/d01-x01-y02"]
analyses["Charged"]["DistChargedMult"][0][55.0] = ["/AMY_1990_I295160/d01-x01-y03"]
analyses["Charged"]["DistChargedMult"][0][56.0] = ["/AMY_1990_I295160/d01-x01-y04"]
analyses["Charged"]["DistChargedMult"][0][57.0] = ["/AMY_1990_I295160/d01-x01-y05"]
analyses["Charged"]["DistChargedMult"][0][60.0] = ["/AMY_1990_I295160/d01-x01-y06"]
analyses["Charged"]["DistChargedMult"][0][60.8] = ["/AMY_1990_I295160/d01-x01-y07"]
analyses["Charged"]["DistChargedMult"][0][61.4] = ["/AMY_1990_I295160/d01-x01-y08"]
analyses["Charged"]["DistChargedMult"][0][55.7] = ["/AMY_1990_I295160/d01-x01-y09"]
analyses["Charged"]["DistChargedMult"][0][91.2] = ["/ALEPH_1991_S2435284/d01-x01-y01","/OPAL_1992_I321190/d01-x01-y01",
"/DELPHI_1991_I301657/d02-x01-y01","/L3_2004_I652683/d59-x01-y01",
- "/ALEPH_1996_S3486095/d18-x01-y01"]
+ "/ALEPH_1996_S3486095/d18-x01-y01","/L3_1992_I334954/d16-x01-y01"]
analyses["Charged"]["DistChargedMult"][2][91.2] = ["/L3_2004_I652683/d59-x01-y02"]
analyses["Charged"]["DistChargedMult"][5][91.2] = ["/L3_2004_I652683/d59-x01-y03"]
analyses["Charged"]["DistChargedMult"][0][130.1] = ["/L3_2004_I652683/d60-x01-y01"]
analyses["Charged"]["DistChargedMult"][0][136.3] = ["/L3_2004_I652683/d60-x01-y02"]
analyses["Charged"]["DistChargedMult"][0][161.0] = ["/OPAL_1997_I440721/d26-x01-y01"]
analyses["Charged"]["DistChargedMult"][0][161.3] = ["/L3_2004_I652683/d60-x01-y03"]
analyses["Charged"]["DistChargedMult"][0][172.0] = ["/OPAL_2000_I513476/d13-x01-y01"]
analyses["Charged"]["DistChargedMult"][0][172.3] = ["/L3_2004_I652683/d61-x01-y01"]
analyses["Charged"]["DistChargedMult"][0][182.8] = ["/L3_2004_I652683/d61-x01-y02"]
analyses["Charged"]["DistChargedMult"][0][183.0] = ["/OPAL_2000_I513476/d13-x01-y02"]
analyses["Charged"]["DistChargedMult"][0][188.6] = ["/L3_2004_I652683/d61-x01-y03"]
analyses["Charged"]["DistChargedMult"][0][189.0] = ["/OPAL_2000_I513476/d13-x01-y03"]
analyses["Charged"]["DistChargedMult"][0][194.4] = ["/L3_2004_I652683/d62-x01-y01"]
analyses["Charged"]["DistChargedMult"][0][200.2] = ["/L3_2004_I652683/d62-x01-y02"]
analyses["Charged"]["DistChargedMult"][0][206.2] = ["/L3_2004_I652683/d62-x01-y03"]
analyses["Charged"]["DistChargedMult"]["C"][91.2]=["/DELPHI_1991_I324035/d01-x01-y01","/DELPHI_1991_I324035/d02-x01-y01",
"/DELPHI_1991_I324035/d03-x01-y01","/DELPHI_1991_I324035/d04-x01-y01",
"/DELPHI_1991_I324035/d05-x01-y01","/DELPHI_1991_I324035/d06-x01-y01",
"/DELPHI_1991_I324035/d07-x01-y01","/DELPHI_1991_I324035/d08-x01-y01",
"/DELPHI_1991_I324035/d09-x01-y01","/DELPHI_1991_I324035/d10-x01-y01",
"/DELPHI_1991_I324035/d11-x01-y01","/DELPHI_1991_I324035/d12-x01-y01",
"/DELPHI_1991_I324035/d13-x01-y01",
"/DELPHI_1992_I334948/d01-x01-y01","/DELPHI_1992_I334948/d01-x01-y02",
"/DELPHI_1992_I334948/d01-x01-y03","/DELPHI_1992_I334948/d02-x01-y01",
"/DELPHI_1992_I334948/d02-x01-y02","/DELPHI_1992_I334948/d02-x01-y03",
"/DELPHI_1992_I334948/d03-x01-y01","/DELPHI_1992_I334948/d03-x01-y02",
"/DELPHI_1992_I334948/d03-x01-y03",]
analyses["Charged"]["DistChargedMult"][21][ 5.25] = ["/OPAL_2004_I631361/d01-x01-y01"]
analyses["Charged"]["DistChargedMult"][21][ 5.98] = ["/OPAL_2004_I631361/d01-x01-y02"]
analyses["Charged"]["DistChargedMult"][21][ 6.98] = ["/OPAL_2004_I631361/d01-x01-y03"]
analyses["Charged"]["DistChargedMult"][21][ 8.43] = ["/OPAL_2004_I631361/d02-x01-y01"]
analyses["Charged"]["DistChargedMult"][21][10.92] = ["/OPAL_2004_I631361/d02-x01-y02"]
analyses["Charged"]["DistChargedMult"][21][14.24] = ["/OPAL_2004_I631361/d03-x01-y01"]
analyses["Charged"]["DistChargedMult"][21][17.72] = ["/OPAL_2004_I631361/d03-x01-y02"]
# charged particle spectra
# xi
analyses["Charged"]["ChargedSpectrum"][0]["xi"][2.2 ] = ["/BESII_2004_I622224/d01-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][2.6 ] = ["/BESII_2004_I622224/d02-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][3.0 ] = ["/BESII_2004_I622224/d03-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][3.2 ] = ["/BESII_2004_I622224/d04-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][4.6 ] = ["/BESII_2004_I622224/d05-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][4.8 ] = ["/BESII_2004_I622224/d06-x01-y01"]
-analyses["Charged"]["ChargedSpectrum"][0]["xi"][12.0 ] = ["/TASSO_1980_I153511/d05-x01-y01","/TASSO_1982_I177174/d02-x01-y01",
- "/TASSO_1982_I177174/d03-x01-y01"]
+analyses["Charged"]["ChargedSpectrum"][0]["xi"][14. ] = ["/TASSO_1990_S2148048/d04-x01-y01"]
+analyses["Charged"]["ChargedSpectrum"][0]["xi"][22. ] = ["/TASSO_1990_S2148048/d04-x01-y02"]
+analyses["Charged"]["ChargedSpectrum"][0]["xi"][35. ] = ["/TASSO_1990_S2148048/d04-x01-y03"]
+analyses["Charged"]["ChargedSpectrum"][0]["xi"][44. ] = ["/TASSO_1990_S2148048/d04-x01-y04"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][58.0 ] = ["/TOPAZ_1995_I381900/d01-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][91.2 ] = ["/ALEPH_1996_S3486095/d17-x01-y01","/DELPHI_1996_S3430090/d08-x01-y01",
- "/L3_2004_I652683/d65-x01-y01","/OPAL_1998_S3780481/d08-x01-y01"]
+ "/L3_2004_I652683/d65-x01-y01","/OPAL_1998_S3780481/d08-x01-y01","/L3_1991_I314407/d06-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][130.1] = ["/L3_2004_I652683/d66-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][133.0] = ["/ALEPH_2004_S5765862/d11-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][136.3] = ["/L3_2004_I652683/d66-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][161.0] = ["/ALEPH_2004_S5765862/d12-x01-y01","/OPAL_1997_I440721/d25-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][161.3] = ["/L3_2004_I652683/d66-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][172.0] = ["/ALEPH_2004_S5765862/d13-x01-y01","/OPAL_2000_I513476/d19-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][172.3] = ["/L3_2004_I652683/d67-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][182.8] = ["/L3_2004_I652683/d67-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][183.0] = ["/DELPHI_2003_I620250/d32-x01-y01","/ALEPH_2004_S5765862/d14-x01-y01",
"/OPAL_2000_I513476/d19-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][188.6] = ["/L3_2004_I652683/d67-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][189.0] = ["/ALEPH_2004_S5765862/d15-x01-y01","/DELPHI_2003_I620250/d32-x01-y02",
"/OPAL_2000_I513476/d19-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][192.0] = ["/DELPHI_2003_I620250/d32-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][194.4] = ["/L3_2004_I652683/d68-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][200.2] = ["/L3_2004_I652683/d68-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][206.2] = ["/L3_2004_I652683/d68-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][196.0] = ["/DELPHI_2003_I620250/d32-x01-y04","/ALEPH_2004_S5765862/d16-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][200.0] = ["/DELPHI_2003_I620250/d33-x01-y01","/ALEPH_2004_S5765862/d17-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][200.5] = ["/OPAL_2003_I595335/d05-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][202.0] = ["/DELPHI_2003_I620250/d33-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][205.0] = ["/DELPHI_2003_I620250/d33-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][206.0] = ["/ALEPH_2004_S5765862/d18-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["xi"][207.0] = ["/DELPHI_2003_I620250/d33-x01-y04"]
# x
-analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 3.0 ] = ["/MARKI_1976_I109792/d02-x01-y01"]
-analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 4.8 ] = ["/MARKI_1976_I109792/d03-x01-y01"]
+analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 3.0 ] = ["/MARKI_1976_I109792/d02-x01-y01","/MARKI_1975_I100733/d03-x01-y01"]
+analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 4.8 ] = ["/MARKI_1976_I109792/d03-x01-y01","/MARKI_1975_I100733/d03-x01-y02"]
+analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 5.2 ] = ["/MARKII_1982_I178416/d01-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 5.8 ] = ["/MARKI_1976_I109792/d04-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 6.2 ] = ["/MARKI_1976_I109792/d05-x01-y01"]
+analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 6.5 ] = ["/MARKII_1982_I178416/d01-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 6.6 ] = ["/MARKI_1976_I109792/d06-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 7.0 ] = ["/MARKI_1976_I109792/d07-x01-y01"]
-analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 7.4 ] = ["/MARKI_1976_I109792/d08-x01-y01"]
+analyses["Charged"]["ChargedSpectrum"][0]["x" ][ 7.4 ] = ["/MARKI_1976_I109792/d08-x01-y01","/MARKI_1975_I100733/d03-x01-y03"]
+analyses["Charged"]["ChargedSpectrum"][0]["x" ][12.0 ] = ["/TASSO_1980_I153511/d05-x01-y01","/TASSO_1982_I177174/d02-x01-y01",
+ "/TASSO_1982_I177174/d03-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][13.0 ] = ["/TASSO_1980_I143691/d05-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][14.0 ] = ["/TASSO_1982_I177174/d01-x01-y01","/TASSO_1982_I177174/d02-x01-y02",
- "/TASSO_1982_I177174/d03-x01-y02"]
+ "/TASSO_1982_I177174/d03-x01-y02","/TASSO_1984_I195333/d06-x01-y01",
+ "/TASSO_1990_S2148048/d02-x01-y01","/TASSO_1990_S2148048/d03-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][19.5 ] = ["/TASSO_1980_I143691/d06-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][22.0 ] = ["/TASSO_1982_I177174/d01-x01-y02","/TASSO_1982_I177174/d02-x01-y03",
- "/TASSO_1982_I177174/d03-x01-y03"]
+ "/TASSO_1982_I177174/d03-x01-y03","/TASSO_1984_I195333/d06-x01-y02",
+ "/TASSO_1990_S2148048/d02-x01-y02","/TASSO_1990_S2148048/d03-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][25.0 ] = ["/TASSO_1982_I177174/d02-x01-y04","/TASSO_1982_I177174/d03-x01-y04"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][29.0 ] = ["/TPC_1988_I262143/d01-x01-y04" ,"/HRS_1985_I201482/d10-x01-y01",
- "/HRS_1985_I201482/d12-x01-y01"]
+ "/HRS_1985_I201482/d12-x01-y01","/MARKII_1988_I246184/d15-x01-y01",
+ "/MARKII_1988_I246184/d33-x01-y01","/MARKII_1988_I246184/d51-x01-y01",
+ "/MARKII_1982_I178416/d01-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][30.0 ] = ["/TASSO_1982_I177174/d02-x01-y05","/TASSO_1982_I177174/d03-x01-y05",
"/TASSO_1980_I143691/d07-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][30.8 ] = ["/TASSO_1980_I153511/d06-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][33.0 ] = ["/TASSO_1982_I177174/d01-x01-y03"]
-analyses["Charged"]["ChargedSpectrum"][0]["x" ][34.0 ] = ["/TASSO_1982_I177174/d02-x01-y06","/TASSO_1982_I177174/d03-x01-y06"]
+analyses["Charged"]["ChargedSpectrum"][0]["x" ][34.0 ] = ["/TASSO_1982_I177174/d02-x01-y06","/TASSO_1982_I177174/d03-x01-y06",
+ "/TASSO_1984_I195333/d06-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][35.0 ] = ["/TASSO_1982_I177174/d02-x01-y07","/TASSO_1982_I177174/d03-x01-y07",
- "/TASSO_1988_I263859/d10-x01-y01"]
+ "/TASSO_1988_I263859/d10-x01-y01",
+ "/TASSO_1990_S2148048/d02-x01-y03","/TASSO_1990_S2148048/d03-x01-y03"]
+analyses["Charged"]["ChargedSpectrum"][0]["x" ][44.0 ] = ["/TASSO_1990_S2148048/d02-x01-y04","/TASSO_1990_S2148048/d03-x01-y04"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][55.2 ] = ["/AMY_1990_I283337/d02-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][91.2 ] = ["/DELPHI_1998_I473409/d16-x01-y01","/DELPHI_1998_I473409/d17-x01-y01",
"/ALEPH_1996_S3486095/d09-x01-y01","/OPAL_1998_S3780481/d04-x01-y01",
"/SLD_2004_S5693039/d01-x01-y01","/SLD_1999_S3743934/d04-x01-y01",
- "/DELPHI_1996_S3430090/d07-x01-y01"]
+ "/DELPHI_1996_S3430090/d07-x01-y01","/L3_1991_I314407/d05-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][133.0] = ["/ALEPH_2004_S5765862/d02-x01-y01","/ALEPH_2004_S5765862/d19-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][161.0] = ["/ALEPH_2004_S5765862/d03-x01-y01","/ALEPH_2004_S5765862/d20-x01-y01",
"/OPAL_1997_I440721/d24-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][172.0] = ["/ALEPH_2004_S5765862/d04-x01-y01","/ALEPH_2004_S5765862/d21-x01-y01",
"/OPAL_2000_I513476/d18-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][183.0] = ["/ALEPH_2004_S5765862/d05-x01-y01","/ALEPH_2004_S5765862/d22-x01-y01",
"/OPAL_2000_I513476/d18-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][189.0] = ["/ALEPH_2004_S5765862/d06-x01-y01","/ALEPH_2004_S5765862/d23-x01-y01",
"/OPAL_2000_I513476/d18-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][196.0] = ["/ALEPH_2004_S5765862/d07-x01-y01","/ALEPH_2004_S5765862/d24-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][200.0] = ["/ALEPH_2004_S5765862/d08-x01-y01","/ALEPH_2004_S5765862/d25-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][200.5] = ["/OPAL_2003_I595335/d04-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][0]["x" ][206.0] = ["/ALEPH_2004_S5765862/d09-x01-y01","/ALEPH_2004_S5765862/d26-x01-y01"]
+# momentum
+analyses["Charged"]["ChargedSpectrum"][0]["p" ][14.] =["/TASSO_1984_I195333/d05-x01-y01"]
+analyses["Charged"]["ChargedSpectrum"][0]["p" ][22.] =["/TASSO_1984_I195333/d05-x01-y02"]
+analyses["Charged"]["ChargedSpectrum"][0]["p" ][34.] =["/TASSO_1984_I195333/d05-x01-y03"]
# with cuts
analyses["Charged"]["ChargedSpectrum"]["C"]["x" ][29.0 ] = ["/HRS_1985_I201482/d11-x01-y01","/HRS_1985_I201482/d13-x01-y01",
"/HRS_1985_I201482/d14-x01-y01","/HRS_1985_I201482/d15-x01-y01"]
# misc
analyses["Charged"]["ChargedSpectrum"][0]["Other"][91.2] = ["/DELPHI_1999_I448370/d01-x01-y01","/DELPHI_1999_I448370/d02-x01-y01",
"/DELPHI_1999_I448370/d03-x01-y01","/DELPHI_1999_I448370/d04-x01-y01",
"/DELPHI_1999_I448370/d05-x01-y01","/DELPHI_1999_I448370/d05-x01-y02",
"/DELPHI_1999_I448370/d05-x01-y03","/DELPHI_1999_I448370/d06-x01-y01",
"/DELPHI_1999_I448370/d06-x01-y02","/DELPHI_1999_I448370/d07-x01-y01",
"/DELPHI_1999_I448370/d07-x01-y02","/DELPHI_1999_I448370/d08-x01-y01",
"/DELPHI_1999_I448370/d08-x01-y02"]
# flavour separated
analyses["Charged"]["ChargedSpectrum"][1]["x" ][91.2] = ["/DELPHI_1998_I473409/d32-x01-y01","/DELPHI_1998_I473409/d33-x01-y01",
"/DELPHI_1997_I428178/d01-x01-y03","/OPAL_1998_S3780481/d01-x01-y01",
"/SLD_2004_S5693039/d08-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][1]["xi"][91.2] = ["/OPAL_1998_S3780481/d05-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][2]["x" ][13.0 ] = ["/OPAL_2004_I648738/d06-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][2]["x" ][28.0 ] = ["/OPAL_2004_I648738/d07-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][2]["x" ][49.0 ] = ["/OPAL_2004_I648738/d08-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][2]["x" ][100.0] = ["/OPAL_2004_I648738/d09-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][2]["x" ][91.2 ] = ["/OPAL_2004_I648738/d10-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][2]["x" ][196.0] = ["/OPAL_2004_I648738/d11-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][2]["xi"][91.2 ] = ["/L3_2004_I652683/d65-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][4]["x" ][91.2 ] = ["/DELPHI_1997_I428178/d01-x01-y02","/OPAL_1998_S3780481/d02-x01-y01",
"/SLD_2004_S5693039/d08-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][4]["xi"][91.2 ] = ["/OPAL_1998_S3780481/d06-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][5]["x" ][13.0 ] = ["/OPAL_2004_I648738/d06-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][5]["x" ][28.0 ] = ["/OPAL_2004_I648738/d07-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][5]["x" ][49.0 ] = ["/OPAL_2004_I648738/d08-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][5]["x" ][100.0] = ["/OPAL_2004_I648738/d09-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][5]["x" ][91.2 ] = ["/DELPHI_1998_I473409/d24-x01-y01","/DELPHI_1998_I473409/d25-x01-y01",
"/DELPHI_1997_I428178/d01-x01-y01","/OPAL_1998_S3780481/d03-x01-y01",
"/SLD_2004_S5693039/d08-x01-y03","/OPAL_2004_I648738/d10-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][5]["xi"][91.2 ] = ["/OPAL_1998_S3780481/d07-x01-y01","/L3_2004_I652683/d65-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][5]["x" ][196.0] = ["/OPAL_2004_I648738/d11-x01-y02"]
# gluons
analyses["Charged"]["ChargedSpectrum"][21]["x"][ 6.5 ] = ["/OPAL_2004_I648738/d06-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][21]["x"][14.0 ] = ["/OPAL_2004_I648738/d07-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][21]["x"][14.24] = ["/OPAL_2004_I631361/d05-x01-y01"]
analyses["Charged"]["ChargedSpectrum"][21]["x"][17.72] = ["/OPAL_2004_I631361/d05-x01-y02"]
analyses["Charged"]["ChargedSpectrum"][21]["x"][24.5 ] = ["/OPAL_2004_I648738/d08-x01-y03"]
analyses["Charged"]["ChargedSpectrum"][21]["x"][50.0 ] = ["/OPAL_2004_I648738/d09-x01-y03"]
# rapidity w.r.t thrust
analyses["Charged"]["ChargedRapidityThrust"][13.0 ] = ["/TASSO_1980_I143691/d02-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][19.5 ] = ["/TASSO_1980_I143691/d03-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][29.0 ] = ["/HRS_1985_I201482/d19-x01-y01","/HRS_1985_I201482/d20-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][30.0 ] = ["/TASSO_1980_I143691/d04-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][55.2 ] = ["/AMY_1990_I283337/d01-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][91.2 ] = ["/DELPHI_1996_S3430090/d05-x01-y01","/ALEPH_1996_S3486095/d10-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][133.0] = ["/ALEPH_2004_S5765862/d36-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][161.0] = ["/ALEPH_2004_S5765862/d37-x01-y01","/OPAL_1997_I440721/d23-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][172.0] = ["/ALEPH_2004_S5765862/d38-x01-y01","/OPAL_2000_I513476/d17-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][183.0] = ["/DELPHI_2003_I620250/d30-x01-y01","/ALEPH_2004_S5765862/d39-x01-y01",
"/OPAL_2000_I513476/d17-x01-y02"]
analyses["Charged"]["ChargedRapidityThrust"][189.0] = ["/DELPHI_2003_I620250/d30-x01-y02","/ALEPH_2004_S5765862/d40-x01-y01",
"/OPAL_2000_I513476/d17-x01-y03"]
analyses["Charged"]["ChargedRapidityThrust"][192.0] = ["/DELPHI_2003_I620250/d30-x01-y03"]
analyses["Charged"]["ChargedRapidityThrust"][196.0] = ["/DELPHI_2003_I620250/d30-x01-y04","/ALEPH_2004_S5765862/d41-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][200.0] = ["/DELPHI_2003_I620250/d31-x01-y01","/ALEPH_2004_S5765862/d42-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][200.5] = ["/OPAL_2003_I595335/d03-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][202.0] = ["/DELPHI_2003_I620250/d31-x01-y02"]
analyses["Charged"]["ChargedRapidityThrust"][205.0] = ["/DELPHI_2003_I620250/d31-x01-y03"]
analyses["Charged"]["ChargedRapidityThrust"][206.0] = ["/ALEPH_2004_S5765862/d43-x01-y01"]
analyses["Charged"]["ChargedRapidityThrust"][207.0] = ["/DELPHI_2003_I620250/d31-x01-y04"]
# pt in w.r.t thrust
analyses["Charged"]["ChargedpTInThrust" ][91.2 ] = ["/DELPHI_1996_S3430090/d01-x01-y01","/ALEPH_1996_S3486095/d11-x01-y01"]
analyses["Charged"]["ChargedpTInThrust" ][133.0] = ["/ALEPH_2004_S5765862/d27-x01-y01"]
analyses["Charged"]["ChargedpTInThrust" ][161.0] = ["/ALEPH_2004_S5765862/d28-x01-y01","/OPAL_1997_I440721/d21-x01-y01"]
analyses["Charged"]["ChargedpTInThrust" ][172.0] = ["/ALEPH_2004_S5765862/d29-x01-y01","/OPAL_2000_I513476/d15-x01-y01"]
analyses["Charged"]["ChargedpTInThrust" ][183.0] = ["/DELPHI_2003_I620250/d34-x01-y01","/ALEPH_2004_S5765862/d30-x01-y01",
"/OPAL_2000_I513476/d15-x01-y02"]
analyses["Charged"]["ChargedpTInThrust" ][189.0] = ["/DELPHI_2003_I620250/d34-x01-y02","/ALEPH_2004_S5765862/d31-x01-y01",
"/OPAL_2000_I513476/d15-x01-y03"]
analyses["Charged"]["ChargedpTInThrust" ][192.0] = ["/DELPHI_2003_I620250/d34-x01-y03"]
analyses["Charged"]["ChargedpTInThrust" ][196.0] = ["/DELPHI_2003_I620250/d34-x01-y04","/ALEPH_2004_S5765862/d32-x01-y01"]
analyses["Charged"]["ChargedpTInThrust" ][200.0] = ["/DELPHI_2003_I620250/d35-x01-y01","/ALEPH_2004_S5765862/d33-x01-y01"]
analyses["Charged"]["ChargedpTInThrust" ][200.5] = ["/OPAL_2003_I595335/d01-x01-y01"]
analyses["Charged"]["ChargedpTInThrust" ][202.0] = ["/DELPHI_2003_I620250/d35-x01-y02"]
analyses["Charged"]["ChargedpTInThrust" ][205.0] = ["/DELPHI_2003_I620250/d35-x01-y03"]
analyses["Charged"]["ChargedpTInThrust" ][206.0] = ["/ALEPH_2004_S5765862/d34-x01-y01"]
analyses["Charged"]["ChargedpTInThrust" ][207.0] = ["/DELPHI_2003_I620250/d35-x01-y04"]
# pt out thrust
analyses["Charged"]["ChargedpTOutThrust"][91.2 ] = ["/DELPHI_1996_S3430090/d02-x01-y01","/ALEPH_1996_S3486095/d12-x01-y01"]
analyses["Charged"]["ChargedpTOutThrust"][161.0] = ["/OPAL_1997_I440721/d22-x01-y01"]
analyses["Charged"]["ChargedpTOutThrust"][172.0] = ["/OPAL_2000_I513476/d16-x01-y01"]
analyses["Charged"]["ChargedpTOutThrust"][183.0] = ["/DELPHI_2003_I620250/d36-x01-y01","/OPAL_2000_I513476/d16-x01-y02"]
analyses["Charged"]["ChargedpTOutThrust"][189.0] = ["/DELPHI_2003_I620250/d36-x01-y02","/OPAL_2000_I513476/d16-x01-y03"]
analyses["Charged"]["ChargedpTOutThrust"][192.0] = ["/DELPHI_2003_I620250/d36-x01-y03"]
analyses["Charged"]["ChargedpTOutThrust"][196.0] = ["/DELPHI_2003_I620250/d36-x01-y04"]
analyses["Charged"]["ChargedpTOutThrust"][200.0] = ["/DELPHI_2003_I620250/d37-x01-y01"]
analyses["Charged"]["ChargedpTOutThrust"][200.5] = ["/OPAL_2003_I595335/d02-x01-y01"]
analyses["Charged"]["ChargedpTOutThrust"][202.0] = ["/DELPHI_2003_I620250/d37-x01-y02"]
analyses["Charged"]["ChargedpTOutThrust"][205.0] = ["/DELPHI_2003_I620250/d37-x01-y03"]
analyses["Charged"]["ChargedpTOutThrust"][206.0] = ["/ALEPH_2004_S5765862/d35-x01-y01"]
analyses["Charged"]["ChargedpTOutThrust"][207.0] = ["/DELPHI_2003_I620250/d37-x01-y04"]
# pT
analyses["Charged"]["ChargedpTThrust" ][29.0] = ["/HRS_1985_I201482/d22-x01-y01","/HRS_1985_I201482/d23-x01-y01"]
analyses["Charged"]["ChargedpTvsxpThrust" ][91.2] = ["/DELPHI_1996_S3430090/d10-x01-y01"]
analyses["Charged"]["ChargedpTOutvsxpThrust"][91.2] = ["/DELPHI_1996_S3430090/d09-x01-y01"]
+analyses["Charged"]["ChargedMultvsThrust" ][57.8] = ["/TOPAZ_1997_I454183/d03-x01-y01"]
# averages
analyses["Charged"]["ChargedAveragepTThrust" ][20.] = ["/PLUTO_1983_I191161/d01-x01-y01"]
analyses["Charged"]["ChargedAveragepT2Thrust" ][20.] = ["/PLUTO_1983_I191161/d01-x01-y02"]
analyses["Charged"]["ChargedSumpTThrust" ][20.] = ["/PLUTO_1983_I191161/d01-x01-y03"]
analyses["Charged"]["ChargedSumpT2Thrust" ][20.] = ["/PLUTO_1983_I191161/d01-x01-y04"]
+analyses["Charged"]["ChargedAveragepTSphericity" ][12.] = ["/TASSO_1984_I195333/d04-x01-y08"]
analyses["Charged"]["ChargedAveragepTSphericity" ][20.] = ["/PLUTO_1983_I191161/d02-x01-y01"]
+analyses["Charged"]["ChargedAveragepT2Sphericity"][12.] = ["/TASSO_1984_I195333/d04-x01-y09"]
analyses["Charged"]["ChargedAveragepT2Sphericity"][20.] = ["/PLUTO_1983_I191161/d02-x01-y02"]
analyses["Charged"]["ChargedSumpTSphericity" ][20.] = ["/PLUTO_1983_I191161/d02-x01-y03"]
analyses["Charged"]["ChargedSumpT2Sphericity" ][20.] = ["/PLUTO_1983_I191161/d02-x01-y04"]
+
+analyses["Charged"]["ChargedAveragepTInThrust" ][172.] = ["/OPAL_2000_I513476/d20-x01-y01"]
+analyses["Charged"]["ChargedAveragepTOutThrust" ][172.] = ["/OPAL_2000_I513476/d20-x01-y02"]
+analyses["Charged"]["ChargedAverageyThrust" ][172.] = ["/OPAL_2000_I513476/d20-x01-y03"]
+analyses["Charged"]["ChargedAveragexThrust" ][172.] = ["/OPAL_2000_I513476/d20-x01-y04"]
+
+
# xF
analyses["Charged"]["ChargedxFThrust"][29.0] = ["/HRS_1985_I201482/d16-x01-y01","/HRS_1985_I201482/d17-x01-y01"]
# rapidity sphericity
+analyses["Charged"]["ChargedRapiditySphericity"][14.0 ] = ["/TASSO_1984_I195333/d14-x01-y01"]
+analyses["Charged"]["ChargedRapiditySphericity"][22.0 ] = ["/TASSO_1984_I195333/d14-x01-y02"]
+analyses["Charged"]["ChargedRapiditySphericity"][29.0 ] = ["/MARKII_1988_I246184/d16-x01-y01",
+ "/MARKII_1988_I246184/d34-x01-y01","/MARKII_1988_I246184/d52-x01-y01"]
+analyses["Charged"]["ChargedRapiditySphericity"][34.0 ] = ["/TASSO_1984_I195333/d14-x01-y03"]
analyses["Charged"]["ChargedRapiditySphericity"][35.0 ] = ["/TASSO_1988_I263859/d11-x01-y01"]
analyses["Charged"]["ChargedRapiditySphericity"][91.2 ] = ["/DELPHI_1996_S3430090/d06-x01-y01"]
analyses["Charged"]["ChargedRapiditySphericity"][133.0] = ["/ALEPH_2004_S5765862/d44-x01-y01"]
analyses["Charged"]["ChargedRapiditySphericity"][161.0] = ["/ALEPH_2004_S5765862/d45-x01-y01"]
analyses["Charged"]["ChargedRapiditySphericity"][172.0] = ["/ALEPH_2004_S5765862/d46-x01-y01"]
analyses["Charged"]["ChargedRapiditySphericity"][183.0] = ["/ALEPH_2004_S5765862/d47-x01-y01"]
analyses["Charged"]["ChargedRapiditySphericity"][189.0] = ["/ALEPH_2004_S5765862/d48-x01-y01"]
analyses["Charged"]["ChargedRapiditySphericity"][196.0] = ["/ALEPH_2004_S5765862/d49-x01-y01"]
analyses["Charged"]["ChargedRapiditySphericity"][200.0] = ["/ALEPH_2004_S5765862/d50-x01-y01"]
analyses["Charged"]["ChargedRapiditySphericity"][206.0] = ["/ALEPH_2004_S5765862/d51-x01-y01"]
# pt in sphericity
+analyses["Charged"]["ChargedpTInSphericity" ][29.0 ] = ["/MARKII_1988_I246184/d14-x01-y01",
+ "/MARKII_1988_I246184/d32-x01-y01","/MARKII_1988_I246184/d50-x01-y01"]
analyses["Charged"]["ChargedpTInSphericity" ][35.0 ] = ["/TASSO_1988_I263859/d07-x01-y01"]
analyses["Charged"]["ChargedpTInSphericity" ][55.2 ] = ["/AMY_1990_I283337/d06-x01-y01"]
analyses["Charged"]["ChargedpTInSphericity" ][91.2 ] = ["/DELPHI_1996_S3430090/d03-x01-y01"]
# pt out sphericity
+analyses["Charged"]["ChargedpTOutSphericity" ][29.0 ] = ["/MARKII_1988_I246184/d13-x01-y01",
+ "/MARKII_1988_I246184/d31-x01-y01","/MARKII_1988_I246184/d49-x01-y01"]
analyses["Charged"]["ChargedpTOutSphericity"][35.0 ] = ["/TASSO_1988_I263859/d08-x01-y01"]
analyses["Charged"]["ChargedpTOutSphericity"][55.2 ] = ["/AMY_1990_I283337/d07-x01-y01"]
analyses["Charged"]["ChargedpTOutSphericity"][91.2 ] = ["/DELPHI_1996_S3430090/d04-x01-y01"]
# others
+analyses["Charged"]["ChargedpLSphericity" ][14. ] = ["/TASSO_1984_I195333/d07-x01-y01","/TASSO_1984_I195333/d10-x01-y01"]
+analyses["Charged"]["ChargedpLSphericity" ][22. ] = ["/TASSO_1984_I195333/d07-x01-y02","/TASSO_1984_I195333/d10-x01-y02"]
+analyses["Charged"]["ChargedpLSphericity" ][34. ] = ["/TASSO_1984_I195333/d07-x01-y03","/TASSO_1984_I195333/d10-x01-y03"]
analyses["Charged"]["ChargedpLSphericity" ][55.2] = ["/AMY_1990_I283337/d03-x01-y01" ]
analyses["Charged"]["ChargedpTSphericity" ][55.2] = ["/AMY_1990_I283337/d04-x01-y01" ]
-analyses["Charged"]["ChargedpTSphericity" ][35.0] = ["/TASSO_1988_I263859/d09-x01-y01"]
+analyses["Charged"]["ChargedpTSphericity" ][29.0 ] = ["/MARKII_1988_I246184/d12-x01-y01",
+ "/MARKII_1988_I246184/d30-x01-y01","/MARKII_1988_I246184/d48-x01-y01"]
+analyses["Charged"]["ChargedpTSphericity" ][14. ] = ["/TASSO_1990_S2148048/d05-x01-y01","/TASSO_1984_I195333/d08-x01-y01",
+ "/TASSO_1984_I195333/d11-x01-y01"]
+analyses["Charged"]["ChargedpTSphericity" ][22. ] = ["/TASSO_1990_S2148048/d05-x01-y02","/TASSO_1984_I195333/d08-x01-y02",
+ "/TASSO_1984_I195333/d11-x01-y02"]
+analyses["Charged"]["ChargedpTSphericity" ][34. ] = ["/TASSO_1984_I195333/d08-x01-y03","/TASSO_1984_I195333/d11-x01-y03"]
+analyses["Charged"]["ChargedpTSphericity" ][35. ] = ["/TASSO_1988_I263859/d09-x01-y01","/TASSO_1990_S2148048/d05-x01-y03"]
+analyses["Charged"]["ChargedpTSphericity" ][44. ] = ["/TASSO_1990_S2148048/d05-x01-y04"]
+analyses["Charged"]["ChargedpT2Sphericity"][14.0 ] = ["/TASSO_1984_I195333/d09-x01-y01"]
+analyses["Charged"]["ChargedpT2Sphericity"][22.0 ] = ["/TASSO_1984_I195333/d09-x01-y02"]
+analyses["Charged"]["ChargedpT2Sphericity"][29.0 ] = ["/MARKII_1988_I246184/d11-x01-y01",
+ "/MARKII_1988_I246184/d29-x01-y01","/MARKII_1988_I246184/d47-x01-y01"]
+analyses["Charged"]["ChargedpT2Sphericity"][34.0 ] = ["/TASSO_1984_I195333/d09-x01-y03"]
analyses["Charged"]["ChargedpT2Sphericity"][55.2] = ["/AMY_1990_I283337/d05-x01-y01" ]
+analyses["Charged"]["ChargedFlowSphericity"][29.0] = ["/MARKII_1988_I246184/d17-x01-y01",
+ "/MARKII_1988_I246184/d35-x01-y01","/MARKII_1988_I246184/d53-x01-y01"]
analyses["Charged"]["ChargedFlowSphericity"][55.2] = ["/AMY_1990_I283337/d10-x01-y01" ]
+analyses["Charged"]["ChargedEnergyFlowSphericity"][29.0] = ["/MARKII_1988_I246184/d18-x01-y01",
+ "/MARKII_1988_I246184/d36-x01-y01","/MARKII_1988_I246184/d54-x01-y01"]
analyses["Charged"]["ChargedEnergyFlowSphericity"][55.2] = ["/AMY_1990_I283337/d11-x01-y01" ]
+analyses["Charged"]["ChargedAveragepT2inSphericity" ][12.0] = ["/TASSO_1984_I195333/d04-x01-y10"]
analyses["Charged"]["ChargedAveragepT2inSphericity" ][29.0] = ["/HRS_1985_I201482/d24-x01-y01"]
analyses["Charged"]["ChargedAveragepT2inSphericity" ][35.0] = ["/TASSO_1988_I263859/d04-x01-y01"]
analyses["Charged"]["ChargedAveragepT2inSphericity" ][55.2] = ["/AMY_1990_I283337/d08-x01-y01"]
+analyses["Charged"]["ChargedAveragepT2outSphericity"][12.0] = ["/TASSO_1984_I195333/d04-x01-y11"]
analyses["Charged"]["ChargedAveragepT2outSphericity"][29.0] = ["/HRS_1985_I201482/d25-x01-y01"]
analyses["Charged"]["ChargedAveragepT2outSphericity"][35.0] = ["/TASSO_1988_I263859/d05-x01-y01"]
analyses["Charged"]["ChargedAveragepT2outSphericity"][55.2] = ["/AMY_1990_I283337/d09-x01-y01"]
# identified particle (flavour sep)
analyses["IdentifiedParticleFlavour"][111 ][5]["x"][91.2]=["/DELPHI_1996_I401100/d03-x01-y01","/SLD_2004_S5693039/d05-x01-y03"]
analyses["IdentifiedParticleFlavour"][211 ][5]["x"][91.2]=["/DELPHI_1998_I473409/d26-x01-y01","/DELPHI_1998_I473409/d27-x01-y01",
"/SLD_1999_S3743934/d10-x01-y03"]
analyses["IdentifiedParticleFlavour"][321 ][5]["x"][91.2]=["/DELPHI_1998_I473409/d28-x01-y01","/DELPHI_1998_I473409/d29-x01-y01",
"/SLD_2004_S5693039/d06-x01-y03","/SLD_1999_S3743934/d12-x01-y03"]
analyses["IdentifiedParticleFlavour"][2212][5]["x"][91.2]=["/DELPHI_1998_I473409/d30-x01-y01","/DELPHI_1998_I473409/d31-x01-y01",
"/SLD_2004_S5693039/d07-x01-y03","/SLD_1999_S3743934/d16-x01-y03"]
analyses["IdentifiedParticleFlavour"][211 ][4]["x"][91.2]=["/SLD_2004_S5693039/d05-x01-y02","/SLD_1999_S3743934/d10-x01-y02"]
analyses["IdentifiedParticleFlavour"][321 ][4]["x"][91.2]=["/SLD_2004_S5693039/d06-x01-y02","/SLD_1999_S3743934/d12-x01-y02"]
analyses["IdentifiedParticleFlavour"][2212][4]["x"][91.2]=["/SLD_2004_S5693039/d07-x01-y02","/SLD_1999_S3743934/d16-x01-y02"]
analyses["IdentifiedParticleFlavour"][211 ][1]["x"][91.2]=["/DELPHI_1998_I473409/d34-x01-y01","/DELPHI_1998_I473409/d35-x01-y01",
"/SLD_2004_S5693039/d05-x01-y01","/SLD_1999_S3743934/d10-x01-y01"]
analyses["IdentifiedParticleFlavour"][321 ][1]["x"][91.2]=["/DELPHI_1998_I473409/d36-x01-y01","/DELPHI_1998_I473409/d37-x01-y01",
"/SLD_2004_S5693039/d06-x01-y01","/SLD_1999_S3743934/d12-x01-y01"]
analyses["IdentifiedParticleFlavour"][2212][1]["x"][91.2]=["/DELPHI_1998_I473409/d38-x01-y01","/DELPHI_1998_I473409/d39-x01-y01",
"/SLD_2004_S5693039/d07-x01-y01","/SLD_1999_S3743934/d16-x01-y01"]
analyses["IdentifiedParticleFlavour"][413][5]["x"][91.2]=["/OPAL_1995_I382219/d04-x01-y01"]
analyses["IdentifiedParticleFlavour"][413][4]["x"][91.2]=["/OPAL_1995_I382219/d05-x01-y01"]
analyses["IdentifiedParticleFlavour"][313 ][1]["x"][91.2]=["/SLD_1999_S3743934/d14-x01-y01"]
analyses["IdentifiedParticleFlavour"][313 ][4]["x"][91.2]=["/SLD_1999_S3743934/d14-x01-y02"]
analyses["IdentifiedParticleFlavour"][313 ][5]["x"][91.2]=["/SLD_1999_S3743934/d14-x01-y03"]
analyses["IdentifiedParticleFlavour"][3122][1]["x"][91.2]=["/SLD_1999_S3743934/d18-x01-y01"]
analyses["IdentifiedParticleFlavour"][3122][4]["x"][91.2]=["/SLD_1999_S3743934/d18-x01-y02"]
analyses["IdentifiedParticleFlavour"][3122][5]["x"][91.2]=["/SLD_1999_S3743934/d18-x01-y03"]
analyses["IdentifiedParticleFlavour"][311 ][1]["x"][91.2]=["/SLD_1999_S3743934/d20-x01-y01"]
analyses["IdentifiedParticleFlavour"][311 ][4]["x"][91.2]=["/SLD_1999_S3743934/d20-x01-y02"]
analyses["IdentifiedParticleFlavour"][311 ][5]["x"][91.2]=["/SLD_1999_S3743934/d20-x01-y03"]
analyses["IdentifiedParticleFlavour"][333 ][1]["x"][91.2]=["/SLD_1999_S3743934/d22-x01-y01"]
analyses["IdentifiedParticleFlavour"][333 ][4]["x"][91.2]=["/SLD_1999_S3743934/d22-x01-y02"]
analyses["IdentifiedParticleFlavour"][333 ][5]["x"][91.2]=["/SLD_1999_S3743934/d22-x01-y03"]
analyses["IdentifiedParticleFlavour"][211 ][41]["x"][91.2]=["/SLD_1999_S3743934/d11-x01-y01"]
analyses["IdentifiedParticleFlavour"][211 ][51]["x"][91.2]=["/SLD_1999_S3743934/d11-x01-y02"]
analyses["IdentifiedParticleFlavour"][321 ][41]["x"][91.2]=["/SLD_1999_S3743934/d13-x01-y01"]
analyses["IdentifiedParticleFlavour"][321 ][51]["x"][91.2]=["/SLD_1999_S3743934/d13-x01-y02"]
analyses["IdentifiedParticleFlavour"][313 ][41]["x"][91.2]=["/SLD_1999_S3743934/d15-x01-y01"]
analyses["IdentifiedParticleFlavour"][313 ][51]["x"][91.2]=["/SLD_1999_S3743934/d15-x01-y02"]
analyses["IdentifiedParticleFlavour"][2212][41]["x"][91.2]=["/SLD_1999_S3743934/d17-x01-y01"]
analyses["IdentifiedParticleFlavour"][2212][51]["x"][91.2]=["/SLD_1999_S3743934/d17-x01-y02"]
analyses["IdentifiedParticleFlavour"][3122][41]["x"][91.2]=["/SLD_1999_S3743934/d19-x01-y01"]
analyses["IdentifiedParticleFlavour"][3122][51]["x"][91.2]=["/SLD_1999_S3743934/d19-x01-y02"]
analyses["IdentifiedParticleFlavour"][311 ][41]["x"][91.2]=["/SLD_1999_S3743934/d21-x01-y01"]
analyses["IdentifiedParticleFlavour"][311 ][51]["x"][91.2]=["/SLD_1999_S3743934/d21-x01-y02"]
analyses["IdentifiedParticleFlavour"][333 ][41]["x"][91.2]=["/SLD_1999_S3743934/d23-x01-y01"]
analyses["IdentifiedParticleFlavour"][333 ][51]["x"][91.2]=["/SLD_1999_S3743934/d23-x01-y02"]
analyses["IdentifiedParticleFlavour"][211][5]["Ratio"][91.2]=["/DELPHI_1998_I473409/d08-x01-y01"]
analyses["IdentifiedParticleFlavour"][211][1]["Ratio"][91.2]=["/DELPHI_1998_I473409/d12-x01-y01"]
analyses["IdentifiedParticleFlavour"][321][5]["Ratio"][91.2]=["/DELPHI_1998_I473409/d09-x01-y01"]
analyses["IdentifiedParticleFlavour"][321][1]["Ratio"][91.2]=["/DELPHI_1998_I473409/d13-x01-y01"]
analyses["IdentifiedParticleFlavour"][2212][5]["Ratio"][91.2]=["/DELPHI_1998_I473409/d10-x01-y01"]
analyses["IdentifiedParticleFlavour"][2212][1]["Ratio"][91.2]=["/DELPHI_1998_I473409/d14-x01-y01"]
analyses["IdentifiedParticleFlavour"]["321/2212"][5]["Ratio"][91.2]=["/DELPHI_1998_I473409/d11-x01-y01"]
analyses["IdentifiedParticleFlavour"]["321/2212"][1]["Ratio"][91.2]=["/DELPHI_1998_I473409/d15-x01-y01"]
analyses["IdentifiedParticleFlavour"][311][4]["Other"][29.0]=["/HRS_1990_I280958/d05-x01-y01"]
analyses["IdentifiedParticleFlavour"][311][1]["Other"][29.0]=["/HRS_1990_I280958/d06-x01-y01"]
analyses["MultiplicityFlavour"]["321/2212"][1][91.2] = ["/DELPHI_1998_I473409/d03-x01-y05"]
analyses["MultiplicityFlavour"]["321/2212"][5][91.2] = ["/DELPHI_1998_I473409/d02-x01-y05"]
analyses["MultiplicityFlavour"][211 ][41][91.2]=["/SLD_1999_S3743934/d25-x01-y01"]
analyses["MultiplicityFlavour"][211 ][51][91.2]=["/SLD_1999_S3743934/d25-x01-y02"]
analyses["MultiplicityFlavour"][321 ][41][91.2]=["/SLD_1999_S3743934/d25-x02-y01"]
analyses["MultiplicityFlavour"][321 ][51][91.2]=["/SLD_1999_S3743934/d25-x02-y02"]
analyses["MultiplicityFlavour"][311 ][41][91.2]=["/SLD_1999_S3743934/d25-x03-y01"]
analyses["MultiplicityFlavour"][311 ][51][91.2]=["/SLD_1999_S3743934/d25-x03-y02"]
analyses["MultiplicityFlavour"][313 ][41][91.2]=["/SLD_1999_S3743934/d25-x04-y01"]
analyses["MultiplicityFlavour"][313 ][51][91.2]=["/SLD_1999_S3743934/d25-x04-y02"]
analyses["MultiplicityFlavour"][333 ][41][91.2]=["/SLD_1999_S3743934/d25-x05-y01"]
analyses["MultiplicityFlavour"][333 ][51][91.2]=["/SLD_1999_S3743934/d25-x05-y02"]
analyses["MultiplicityFlavour"][2212][41][91.2]=["/SLD_1999_S3743934/d25-x06-y01"]
analyses["MultiplicityFlavour"][2212][51][91.2]=["/SLD_1999_S3743934/d25-x06-y02"]
analyses["MultiplicityFlavour"][3122][41][91.2]=["/SLD_1999_S3743934/d25-x07-y01"]
analyses["MultiplicityFlavour"][3122][51][91.2]=["/SLD_1999_S3743934/d25-x07-y02"]
analyses["MultiplicityFlavour"][211 ][1][91.2]=["/SLD_2004_S5693039/d05-x02-y01","/SLD_1999_S3743934/d24-x01-y02",
"/DELPHI_1998_I473409/d03-x01-y02"]
analyses["MultiplicityFlavour"][211 ][4][91.2]=["/SLD_2004_S5693039/d05-x02-y02","/SLD_1999_S3743934/d24-x01-y03"]
analyses["MultiplicityFlavour"][211 ][5][91.2]=["/SLD_2004_S5693039/d05-x02-y03","/SLD_1999_S3743934/d24-x01-y04",
"/DELPHI_1998_I473409/d02-x01-y02"]
analyses["MultiplicityFlavour"][321 ][1][91.2]=["/SLD_2004_S5693039/d06-x02-y01","/SLD_1999_S3743934/d24-x02-y02",
"/DELPHI_1998_I473409/d03-x01-y03"]
analyses["MultiplicityFlavour"][321 ][4][91.2]=["/SLD_2004_S5693039/d06-x02-y02","/SLD_1999_S3743934/d24-x02-y03"]
analyses["MultiplicityFlavour"][321 ][5][91.2]=["/SLD_2004_S5693039/d06-x02-y03","/SLD_1999_S3743934/d24-x02-y04",
"/DELPHI_1998_I473409/d02-x01-y03"]
analyses["MultiplicityFlavour"][311 ][1][91.2]=["/SLD_1999_S3743934/d24-x03-y02"]
analyses["MultiplicityFlavour"][311 ][4][91.2]=["/SLD_1999_S3743934/d24-x03-y03"]
analyses["MultiplicityFlavour"][311 ][5][91.2]=["/SLD_1999_S3743934/d24-x03-y04"]
analyses["MultiplicityFlavour"][313 ][1][91.2]=["/SLD_1999_S3743934/d24-x04-y02"]
analyses["MultiplicityFlavour"][313 ][4][91.2]=["/SLD_1999_S3743934/d24-x04-y03"]
analyses["MultiplicityFlavour"][313 ][5][91.2]=["/SLD_1999_S3743934/d24-x04-y04"]
analyses["MultiplicityFlavour"][333 ][1][91.2]=["/SLD_1999_S3743934/d24-x05-y02"]
analyses["MultiplicityFlavour"][333 ][4][91.2]=["/SLD_1999_S3743934/d24-x05-y03"]
analyses["MultiplicityFlavour"][333 ][5][91.2]=["/SLD_1999_S3743934/d24-x05-y04"]
analyses["MultiplicityFlavour"][2212][1][91.2]=["/SLD_2004_S5693039/d07-x02-y01","/SLD_1999_S3743934/d24-x06-y02",
"/DELPHI_1998_I473409/d03-x01-y04"]
analyses["MultiplicityFlavour"][2212][4][91.2]=["/SLD_2004_S5693039/d07-x02-y02","/SLD_1999_S3743934/d24-x06-y03"]
analyses["MultiplicityFlavour"][2212][5][91.2]=["/SLD_2004_S5693039/d07-x02-y03","/SLD_1999_S3743934/d24-x06-y04",
"/DELPHI_1998_I473409/d02-x01-y04"]
analyses["MultiplicityFlavour"][3122][1][91.2]=["/SLD_1999_S3743934/d24-x07-y02"]
analyses["MultiplicityFlavour"][3122][4][91.2]=["/SLD_1999_S3743934/d24-x07-y03"]
analyses["MultiplicityFlavour"][3122][5][91.2]=["/SLD_1999_S3743934/d24-x07-y04"]
# identified particle distributions
# photons
# x_E
-analyses["IdentifiedParticle"][22 ]["x" ][14.0]=["/CELLO_1983_I191415/d01-x01-y01"]
+analyses["IdentifiedParticle"][22 ]["x" ][14.0]=["/CELLO_1983_I191415/d01-x01-y01","/JADE_1985_I213948/d03-x01-y01"]
analyses["IdentifiedParticle"][22 ]["x" ][22.0]=["/CELLO_1983_I191415/d02-x01-y01"]
+analyses["IdentifiedParticle"][22 ]["x" ][22.5]=["/JADE_1985_I213948/d02-x01-y01"]
analyses["IdentifiedParticle"][22 ]["x" ][29.0]=["/TPC_1985_I205868/d01-x01-y01" ]
analyses["IdentifiedParticle"][22 ]["x" ][34.0]=["/CELLO_1983_I191415/d03-x01-y01"]
+analyses["IdentifiedParticle"][22 ]["x" ][34.4]=["/JADE_1985_I213948/d01-x01-y01"]
analyses["IdentifiedParticle"][22 ]["x" ][35.0]=["/CELLO_1989_I276764/d02-x01-y01","/JADE_1990_I282847/d01-x01-y01"]
analyses["IdentifiedParticle"][22 ]["x" ][44.0]=["/JADE_1990_I282847/d02-x01-y01"]
analyses["IdentifiedParticle"][22 ]["x" ][91.2]=["/OPAL_1998_S3749908/d02-x01-y01"]
# xi
analyses["IdentifiedParticle"][22 ]["xi"][91.2]=["/ALEPH_1996_S3486095/d28-x01-y01","/OPAL_1998_S3749908/d03-x01-y01"]
# charged pions
# x
analyses["IdentifiedParticle"][211 ]["x" ][3.635] = ["/DASP_1979_I132045/d18-x01-y01"]
analyses["IdentifiedParticle"][211 ]["x" ][4.04 ] = ["/DASP_1979_I132045/d18-x01-y02"]
analyses["IdentifiedParticle"][211 ]["x" ][4.17 ] = ["/DASP_1979_I132045/d18-x01-y03"]
analyses["IdentifiedParticle"][211 ]["x" ][4.30 ] = ["/DASP_1979_I132045/d18-x01-y04"]
analyses["IdentifiedParticle"][211 ]["x" ][4.41 ] = ["/DASP_1979_I132045/d18-x01-y05"]
analyses["IdentifiedParticle"][211 ]["x" ][4.72 ] = ["/DASP_1979_I132045/d18-x01-y06"]
analyses["IdentifiedParticle"][211 ]["x" ][5.0 ] = ["/DASP_1979_I132045/d18-x01-y07"]
analyses["IdentifiedParticle"][211 ]["x" ][5.2 ] = ["/DASP_1979_I132045/d18-x01-y08"]
analyses["IdentifiedParticle"][211 ]["x" ][10.0 ] = ["/ARGUS_1989_I276860/d09-x01-y02"]
analyses["IdentifiedParticle"][211 ]["x" ][10.52] = ["/BELLE_2013_I1216515/d01-x01-y01"]
analyses["IdentifiedParticle"][211 ]["x" ][12.0 ] = ["/TASSO_1980_I153656/d02-x01-y02"]
analyses["IdentifiedParticle"][211 ]["x" ][14.0 ] = ["/TASSO_1983_I181470/d20-x01-y01"]
analyses["IdentifiedParticle"][211 ]["x" ][22.0 ] = ["/TASSO_1983_I181470/d22-x01-y01"]
-analyses["IdentifiedParticle"][211 ]["x" ][29.0 ] = ["/TPC_1988_I262143/d01-x01-y01","/TPC_1988_I262143/d05-x01-y01"]
+analyses["IdentifiedParticle"][211 ]["x" ][29.0 ] = ["/TPC_1988_I262143/d01-x01-y01","/TPC_1988_I262143/d05-x01-y01",
+ "/HRS_1987_I215848/d02-x01-y01"]
analyses["IdentifiedParticle"][211 ]["x" ][30.0 ] = ["/TASSO_1980_I153656/d05-x01-y02"]
analyses["IdentifiedParticle"][211 ]["x" ][34.0 ] = ["/TASSO_1989_I267755/d07-x01-y01","/TASSO_1983_I181470/d24-x01-y01"]
analyses["IdentifiedParticle"][211 ]["x" ][44.0 ] = ["/TASSO_1989_I267755/d10-x01-y01"]
analyses["IdentifiedParticle"][211 ]["x" ][91.2 ] = ["/ALEPH_1995_I382179/d01-x01-y01","/DELPHI_1998_I473409/d19-x01-y01",
"/ALEPH_1996_S3486095/d25-x01-y01","/SLD_2004_S5693039/d02-x01-y02",
"/SLD_1999_S3743934/d01-x01-y02"]
analyses["IdentifiedParticle"][211 ]["Other" ][91.2 ] = ["/SLD_1999_S3743934/d26-x01-y01","/SLD_1999_S3743934/d26-x01-y02",
"/SLD_1999_S3743934/d27-x01-y01","/SLD_2004_S5693039/d09-x01-y01",
"/SLD_2004_S5693039/d09-x01-y02","/SLD_2004_S5693039/d09-x01-y03",]
# p
analyses["IdentifiedParticle"][211 ]["p" ][3.635] = ["/DASP_1979_I132045/d01-x01-y01"]
analyses["IdentifiedParticle"][211 ]["p" ][4.04 ] = ["/DASP_1979_I132045/d01-x01-y02"]
analyses["IdentifiedParticle"][211 ]["p" ][4.17 ] = ["/DASP_1979_I132045/d01-x01-y03"]
analyses["IdentifiedParticle"][211 ]["p" ][4.30 ] = ["/DASP_1979_I132045/d01-x01-y04"]
analyses["IdentifiedParticle"][211 ]["p" ][4.41 ] = ["/DASP_1979_I132045/d01-x01-y05"]
analyses["IdentifiedParticle"][211 ]["p" ][4.72 ] = ["/DASP_1979_I132045/d01-x01-y06"]
analyses["IdentifiedParticle"][211 ]["p" ][5.0 ] = ["/DASP_1979_I132045/d01-x01-y07"]
analyses["IdentifiedParticle"][211 ]["p" ][5.2 ] = ["/DASP_1979_I132045/d01-x01-y08"]
analyses["IdentifiedParticle"][211 ]["p" ][10.0 ] = ["/ARGUS_1989_I276860/d05-x01-y02"]
analyses["IdentifiedParticle"][211 ]["p" ][10.54] = ["/BABAR_2013_I1238276/d01-x01-y01","/BABAR_2013_I1238276/d02-x01-y01",
"/CLEO_1985_I205668/d01-x01-y01"]
analyses["IdentifiedParticle"][211 ]["p" ][12.0 ] = ["/TASSO_1980_I153656/d02-x01-y01"]
analyses["IdentifiedParticle"][211 ]["p" ][14.0 ] = ["/TASSO_1983_I181470/d19-x01-y01"]
analyses["IdentifiedParticle"][211 ]["p" ][22.0 ] = ["/TASSO_1983_I181470/d25-x01-y01"]
analyses["IdentifiedParticle"][211 ]["p" ][30.0 ] = ["/TASSO_1980_I153656/d05-x01-y01"]
analyses["IdentifiedParticle"][211 ]["p" ][34.0 ] = ["/TASSO_1983_I181470/d13-x01-y01"]
analyses["IdentifiedParticle"][211 ]["p" ][91.2 ] = ["/DELPHI_1998_I473409/d18-x01-y01","/OPAL_1994_S2927284/d01-x01-y01"]
# xi
analyses["IdentifiedParticle"][211 ]["xi"][58.0 ] = ["/TOPAZ_1995_I381900/d02-x01-y01"]
# ratios
analyses["IdentifiedParticle"][211 ]["Ratio"][12.0 ] = ["/TASSO_1980_I153656/d08-x01-y01"]
analyses["IdentifiedParticle"][211 ]["Ratio"][29.0 ] = ["/TPC_1988_I262143/d06-x01-y01"]
analyses["IdentifiedParticle"][211 ]["Ratio"][30.0 ] = ["/TASSO_1980_I153656/d11-x01-y01"]
analyses["IdentifiedParticle"][211 ]["Ratio"][34.0 ] = ["/TASSO_1989_I267755/d01-x01-y01"]
analyses["IdentifiedParticle"][211 ]["Ratio"][44.0 ] = ["/TASSO_1989_I267755/d04-x01-y01"]
analyses["IdentifiedParticle"][211 ]["Ratio"][91.2 ] = ["/DELPHI_1998_I473409/d04-x01-y01","/SLD_1999_S3743934/d01-x01-y01"]
# neutral pions
# x
analyses["IdentifiedParticle"][111 ]["x" ][10.0]=["/ARGUS_1990_I278933/d03-x01-y01","/ARGUS_1990_I278933/d03-x01-y02",
"/CLEO_1985_I205668/d04-x01-y01",
"/CRYSTAL_BALL_1991_I297905/d03-x01-y02",
"/CRYSTAL_BALL_1991_I297905/d03-x01-y01"]
analyses["IdentifiedParticle"][111 ]["x" ][14.0]=["/TASSO_1982_I168232/d02-x03-y03","/CELLO_1983_I191415/d04-x01-y01","/JADE_1985_I213948/d06-x01-y01"]
analyses["IdentifiedParticle"][111 ]["x" ][22.0]=["/CELLO_1983_I191415/d05-x01-y01"]
+analyses["IdentifiedParticle"][111 ]["x" ][22.5]=["/JADE_1985_I213948/d05-x01-y01"]
analyses["IdentifiedParticle"][111 ]["x" ][29.0]=["/TPC_1985_I205868/d02-x01-y01" ]
analyses["IdentifiedParticle"][111 ]["x" ][34.0]=["/TASSO_1982_I168232/d03-x03-y03","/TASSO_1986_I230950/d02-x01-y01",
"/CELLO_1983_I191415/d06-x01-y01"]
+analyses["IdentifiedParticle"][111 ]["x" ][34.4 ] = ["/JADE_1985_I213948/d04-x01-y01"]
analyses["IdentifiedParticle"][111 ]["x" ][35.0]=["/CELLO_1989_I276764/d03-x01-y01","/CELLO_1989_I276764/d04-x01-y01",
"/JADE_1990_I282847/d03-x01-y01"]
analyses["IdentifiedParticle"][111 ]["x" ][44.0]=["/TASSO_1989_I267755/d13-x01-y01","/JADE_1990_I282847/d04-x01-y01"]
analyses["IdentifiedParticle"][111 ]["x" ][91.2]=["/DELPHI_1996_I401100/d01-x01-y01","/ALEPH_1996_S3486095/d29-x01-y01",
"/OPAL_1998_S3749908/d04-x01-y01","/ALEPH_1997_I427131/d02-x01-y02",
"/ALEPH_2000_I507531/d01-x01-y01","/ALEPH_2000_I507531/d04-x01-y01",
"/ALEPH_2000_I507531/d07-x01-y01","/ALEPH_2000_I507531/d08-x01-y01",
- "/ALEPH_2000_I507531/d09-x01-y01"]
+ "/ALEPH_2000_I507531/d09-x01-y01",
+ "/L3_1994_I374698/d05-x01-y01","/L3_1994_I374698/d06-x01-y01","/L3_1991_I314407/d03-x01-y01"]
# p/E
analyses["IdentifiedParticle"][111 ]["p" ][14.0]=["/TASSO_1982_I168232/d02-x01-y01","/TASSO_1982_I168232/d02-x02-y02"]
analyses["IdentifiedParticle"][111 ]["p" ][34.0]=["/TASSO_1982_I168232/d03-x01-y01","/TASSO_1982_I168232/d03-x02-y02",
"/TASSO_1986_I230950/d01-x01-y01"]
# xi
-analyses["IdentifiedParticle"][111 ]["xi"][91.2]=["/OPAL_1998_S3749908/d05-x01-y01"]
+analyses["IdentifiedParticle"][111 ]["xi"][91.2]=["/OPAL_1998_S3749908/d05-x01-y01","/L3_1994_I374698/d07-x01-y01","/L3_1991_I314407/d04-x01-y01"]
# others
analyses["IdentifiedParticle"][111 ]["Other"][91.2]=["/ALEPH_1997_I427131/d03-x01-y01","/ALEPH_1997_I427131/d04-x01-y01"]
# eta
-#
+#x
analyses["IdentifiedParticle"][221 ]["x" ][10.0]=["/ARGUS_1990_I278933/d05-x01-y01","/ARGUS_1990_I278933/d05-x01-y02",
"/CRYSTAL_BALL_1991_I297905/d05-x01-y01",
"/CRYSTAL_BALL_1991_I297905/d05-x01-y02"]
analyses["IdentifiedParticle"][221 ]["x" ][29.0]=["/HRS_1988_I250824/d01-x01-y01","/MARKII_1988_I261194/d01-x01-y01"]
analyses["IdentifiedParticle"][221 ]["x" ][34.4]=["/JADE_1985_I213948/d07-x01-y01"]
analyses["IdentifiedParticle"][221 ]["x" ][35.0]=["/CELLO_1989_I276764/d05-x01-y01" ,"/JADE_1990_I282847/d05-x01-y01"]
analyses["IdentifiedParticle"][221 ]["x" ][91.2]=["/ALEPH_2002_S4823664/d02-x01-y02","/L3_1992_I336180/d01-x01-y01",
"/ALEPH_1996_S3486095/d30-x01-y01","/OPAL_1998_S3749908/d06-x01-y01",
"/ALEPH_2000_I507531/d02-x01-y01","/ALEPH_2000_I507531/d05-x01-y01",
"/ALEPH_2000_I507531/d10-x01-y01","/ALEPH_2000_I507531/d11-x01-y01",
- "/ALEPH_2000_I507531/d12-x01-y01"]
+ "/ALEPH_2000_I507531/d12-x01-y01",
+ "/L3_1994_I374698/d08-x01-y01","/L3_1994_I374698/d09-x01-y01"]
# xi
-analyses["IdentifiedParticle"][221 ]["xi"][91.2]=["/L3_1992_I336180/d02-x01-y01","/OPAL_1998_S3749908/d07-x01-y01"]
+analyses["IdentifiedParticle"][221 ]["xi"][91.2]=["/L3_1992_I336180/d02-x01-y01","/OPAL_1998_S3749908/d07-x01-y01","/L3_1994_I374698/d10-x01-y01"]
# eta'
# x
analyses["IdentifiedParticle"][331 ]["x" ][91.2]=["/L3_1997_I427107/d07-x01-y01" ,"/L3_1997_I427107/d09-x01-y01",
"/ALEPH_1996_S3486095/d31-x01-y01","/OPAL_1998_S3749908/d12-x01-y01",
"/ALEPH_2000_I507531/d03-x01-y01","/ALEPH_2000_I507531/d06-x01-y01",
"/ALEPH_2000_I507531/d13-x01-y01","/ALEPH_2000_I507531/d14-x01-y01",
"/ALEPH_2000_I507531/d15-x01-y01"]
# xi
analyses["IdentifiedParticle"][331 ]["xi"][91.2]=["/L3_1997_I427107/d08-x01-y01","/L3_1997_I427107/d10-x01-y01",
"/OPAL_1998_S3749908/d13-x01-y01"]
# rho +/-
analyses["IdentifiedParticle"][213 ]["x" ][91.2] = ["/OPAL_1998_S3749908/d08-x01-y01"]
analyses["IdentifiedParticle"][213 ]["xi"][91.2] = ["/OPAL_1998_S3749908/d09-x01-y01"]
# rho0
analyses["IdentifiedParticle"][113 ]["x" ][10.0] = ["/ARGUS_1993_S2789213/d10-x01-y01","/CLEO_1985_I205668/d08-x01-y01"]
+analyses["IdentifiedParticle"][113 ]["x" ][29.0] = ["/HRS_1989_I276948/d01-x01-y01"]
+analyses["IdentifiedParticle"][113 ]["x" ][34.0] = ["/TASSO_1982_I179022/d01-x01-y01"]
analyses["IdentifiedParticle"][113 ]["x" ][35.0] = ["/JADE_1984_I203145/d02-x01-y01"]
analyses["IdentifiedParticle"][113 ]["x" ][91.2] = ["/DELPHI_1999_S3960137/d01-x01-y01","/ALEPH_1996_S3486095/d37-x01-y01"]
# omega
analyses["IdentifiedParticle"][223 ]["x" ][10.0] = ["/ARGUS_1993_S2789213/d13-x01-y01"]
analyses["IdentifiedParticle"][223 ]["x" ][91.2] = ["/ALEPH_2002_S4823664/d03-x01-y02","/L3_1997_I427107/d05-x01-y01",
"/ALEPH_1996_S3486095/d38-x01-y01","/OPAL_1998_S3749908/d10-x01-y01",]
analyses["IdentifiedParticle"][223 ]["xi"][91.2] = ["/L3_1997_I427107/d06-x01-y01","/OPAL_1998_S3749908/d11-x01-y01"]
# phi
analyses["IdentifiedParticle"][333 ]["x" ][10.0] = ["/ARGUS_1989_I262551/d01-x01-y01","/CLEO_1985_I205668/d11-x01-y01"]
-analyses["IdentifiedParticle"][333 ]["x" ][29.0] = ["/TPC_1984_I200105/d01-x01-y01"]
+analyses["IdentifiedParticle"][333 ]["x" ][29.0] = ["/TPC_1984_I200105/d01-x01-y01","/HRS_1985_I213242/d01-x01-y01"]
analyses["IdentifiedParticle"][333 ]["x" ][91.2] = ["/DELPHI_1996_I420528/d03-x01-y01","/ALEPH_1996_S3486095/d40-x01-y01",
"/OPAL_1998_S3702294/d02-x01-y03","/SLD_1999_S3743934/d09-x01-y01"]
analyses["IdentifiedParticle"][333 ]["Other"][29.0] = ["/TPC_1984_I200105/d03-x01-y01"]
# f_2
+analyses["IdentifiedParticle"][225]["x" ][29. ]=["/HRS_1986_I18688/d01-x01-y01"]
analyses["IdentifiedParticle"][225]["x" ][91.2]=["/DELPHI_1999_S3960137/d01-x01-y03","/OPAL_1998_S3702294/d02-x01-y02"]
# f_2'
analyses["IdentifiedParticle"][335]["x" ][91.2]=["/DELPHI_1996_I416741/d01-x01-y01"]
# f_0(980)
analyses["IdentifiedParticle"][9010221]["x" ][10.0]=["/ARGUS_1993_S2669951/d02-x01-y01"]
+analyses["IdentifiedParticle"][9010221]["x" ][29. ]=["/HRS_1986_I18688/d01-x01-y02"]
analyses["IdentifiedParticle"][9010221]["x" ][91.2]=["/DELPHI_1999_S3960137/d01-x01-y02","/OPAL_1998_S3702294/d02-x01-y01"]
-# a_0 =/-
+# a_0 +/-
analyses["IdentifiedParticle"][9000211]["x" ][91.2]=["/OPAL_1998_S3749908/d14-x01-y01"]
analyses["IdentifiedParticle"][9000211]["xi" ][91.2]=["/OPAL_1998_S3749908/d15-x01-y01"]
+# f_1
+analyses["IdentifiedParticle"][20223]["x"][91.2]=["/DELPHI_2003_I628566/d02-x01-y01"]
+# f_1'
+analyses["IdentifiedParticle"][20333]["x"][91.2]=["/DELPHI_2003_I628566/d02-x01-y02"]
# strange mesons
# K0
# x
analyses["IdentifiedParticle"][311 ]["x" ][3.63] = ["/PLUTO_1977_I118873/d02-x01-y01"]
analyses["IdentifiedParticle"][311 ]["x" ][4.03] = ["/PLUTO_1977_I118873/d03-x01-y01"]
analyses["IdentifiedParticle"][311 ]["x" ][4.5] = ["/PLUTO_1977_I118873/d04-x01-y01"]
analyses["IdentifiedParticle"][311 ]["x" ][9.4] = ["/PLUTO_1981_I165122/d05-x01-y01"]
analyses["IdentifiedParticle"][311 ]["x" ][10.0] = ["/ARGUS_1989_I276860/d11-x01-y02","/CLEO_1985_I205668/d05-x01-y01"]
analyses["IdentifiedParticle"][311 ]["x" ][14.0] = ["/TASSO_1980_I153341/d04-x01-y01","/TASSO_1985_I205119/d01-x01-y01"]
analyses["IdentifiedParticle"][311 ]["x" ][22.0] = ["/TASSO_1985_I205119/d02-x01-y01"]
-analyses["IdentifiedParticle"][311 ]["x" ][29.0] = ["/TPC_1984_I205869/d04-x01-y01","/HRS_1990_I280958/d03-x01-y01"]
+analyses["IdentifiedParticle"][311 ]["x" ][29.0] = ["/TPC_1984_I205869/d04-x01-y01","/HRS_1990_I280958/d03-x01-y01",
+ "/MARKII_1985_I207785/d02-x01-y01","/HRS_1987_I215848/d05-x01-y01"]
analyses["IdentifiedParticle"][311 ]["x" ][30.0] = ["/PLUTO_1981_I165122/d04-x01-y01"]
analyses["IdentifiedParticle"][311 ]["x" ][34.0] = ["/TASSO_1985_I205119/d03-x01-y01"]
analyses["IdentifiedParticle"][311 ]["x" ][34.5] = ["/TASSO_1990_I284251/d01-x01-y03"]
analyses["IdentifiedParticle"][311 ]["x" ][35.0] = ["/TASSO_1990_I284251/d01-x01-y02","/CELLO_1990_I283026/d01-x01-y01"]
analyses["IdentifiedParticle"][311 ]["x" ][42.6] = ["/TASSO_1990_I284251/d01-x01-y01"]
analyses["IdentifiedParticle"][311 ]["x" ][91.2] = ["/OPAL_2000_S4418603/d03-x01-y01","/DELPHI_1995_I377487/d08-x01-y01",
"/ALEPH_1996_S3486095/d32-x01-y01","/SLD_1999_S3743934/d05-x01-y01",
"/OPAL_1995_I393503/d02-x01-y01"]
# p
analyses["IdentifiedParticle"][311 ]["p" ][10.0] = ["/ARGUS_1989_I276860/d07-x01-y02"]
analyses["IdentifiedParticle"][311 ]["p" ][14.0] = ["/TASSO_1980_I153341/d02-x01-y01","/TASSO_1985_I205119/d07-x01-y01"]
analyses["IdentifiedParticle"][311 ]["p" ][22.0] = ["/TASSO_1985_I205119/d08-x01-y01"]
analyses["IdentifiedParticle"][311 ]["p" ][34.0] = ["/TASSO_1985_I205119/d09-x01-y01"]
# xi
analyses["IdentifiedParticle"][311 ]["xi" ][58.0] = ["/TOPAZ_1995_I381900/d03-x01-y01"]
analyses["IdentifiedParticle"][311 ]["xi" ][91.2] = ["/DELPHI_1995_I377487/d09-x01-y01","/OPAL_1995_I393503/d03-x01-y01",
"/ALEPH_2000_I507531/d16-x01-y01","/ALEPH_2000_I507531/d18-x01-y01",
"/ALEPH_2000_I507531/d20-x01-y01","/ALEPH_2000_I507531/d21-x01-y01",
"/ALEPH_2000_I507531/d21-x01-y01"]
+analyses["IdentifiedParticle"][311 ]["xi" ][183. ] =["/DELPHI_2001_I526164/d16-x01-y01"]
+analyses["IdentifiedParticle"][311 ]["xi" ][189. ] =["/DELPHI_2001_I526164/d16-x01-y02"]
# other
analyses["IdentifiedParticle"][311 ]["Other"][14.8 ] = ["/TASSO_1990_I284251/d06-x01-y01","/TASSO_1990_I284251/d06-x01-y02"]
analyses["IdentifiedParticle"][311 ]["Other"][21.5 ] = ["/TASSO_1990_I284251/d07-x01-y01","/TASSO_1990_I284251/d07-x01-y02"]
analyses["IdentifiedParticle"][311 ]["Other"][29.0 ] = ["/HRS_1990_I280958/d04-x01-y01"]
analyses["IdentifiedParticle"][311 ]["Other"][35.0 ] = ["/TASSO_1990_I284251/d05-x01-y03","/TASSO_1990_I284251/d05-x01-y04"]
analyses["IdentifiedParticle"][311 ]["Other"][42.6 ] = ["/TASSO_1990_I284251/d05-x01-y01","/TASSO_1990_I284251/d05-x01-y02"]
# K+/-
# x
analyses["IdentifiedParticle"][321 ]["x" ][3.635] = ["/DASP_1979_I132045/d19-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][4.04 ] = ["/DASP_1979_I132045/d20-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][4.17 ] = ["/DASP_1979_I132045/d21-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][4.30 ] = ["/DASP_1979_I132045/d22-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][4.41 ] = ["/DASP_1979_I132045/d23-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][4.72 ] = ["/DASP_1979_I132045/d24-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][5.0 ] = ["/DASP_1979_I132045/d25-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][5.2 ] = ["/DASP_1979_I132045/d26-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][10.0 ] = ["/ARGUS_1989_I276860/d10-x01-y02"]
analyses["IdentifiedParticle"][321 ]["x" ][10.52] = ["/BELLE_2013_I1216515/d01-x01-y02","/CLEO_1985_I205668/d02-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][12.0 ] = ["/TASSO_1980_I153656/d03-x01-y02"]
analyses["IdentifiedParticle"][321 ]["x" ][14.0 ] = ["/TASSO_1983_I181470/d26-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][22.0 ] = ["/TASSO_1983_I181470/d10-x01-y01"]
-analyses["IdentifiedParticle"][321 ]["x" ][29.0 ] = ["/TPC_1988_I262143/d01-x01-y02","/TPC_1988_I262143/d05-x01-y02"]
+analyses["IdentifiedParticle"][321 ]["x" ][29.0 ] = ["/TPC_1988_I262143/d01-x01-y02","/TPC_1988_I262143/d05-x01-y02",
+ "/MARKII_1985_I207785/d04-x01-y01","/HRS_1987_I215848/d03-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][30.0 ] = ["/TASSO_1980_I153656/d06-x01-y02"]
analyses["IdentifiedParticle"][321 ]["x" ][34.0 ] = ["/TASSO_1989_I267755/d08-x01-y01","/TASSO_1983_I181470/d12-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][44.0 ] = ["/TASSO_1989_I267755/d11-x01-y01"]
analyses["IdentifiedParticle"][321 ]["x" ][91.2 ] = ["/ALEPH_1995_I382179/d02-x01-y01","/DELPHI_1995_I394052/d05-x01-y01",
"/DELPHI_1998_I473409/d21-x01-y01","/SLD_1999_S3743934/d02-x01-y02",
"/ALEPH_1996_S3486095/d26-x01-y01","/SLD_2004_S5693039/d03-x01-y02"]
# p
analyses["IdentifiedParticle"][321 ]["p" ][3.635] = ["/DASP_1979_I132045/d02-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][4.04 ] = ["/DASP_1979_I132045/d03-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][4.17 ] = ["/DASP_1979_I132045/d04-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][4.30 ] = ["/DASP_1979_I132045/d05-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][4.41 ] = ["/DASP_1979_I132045/d06-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][4.72 ] = ["/DASP_1979_I132045/d07-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][5.0 ] = ["/DASP_1979_I132045/d08-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][5.2 ] = ["/DASP_1979_I132045/d09-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][10.0 ] = ["/ARGUS_1989_I276860/d06-x01-y02"]
analyses["IdentifiedParticle"][321 ]["p" ][10.54] = ["/BABAR_2013_I1238276/d01-x01-y02","/BABAR_2013_I1238276/d02-x01-y02"]
analyses["IdentifiedParticle"][321 ]["p" ][12.0 ] = ["/TASSO_1980_I153656/d03-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][14.0 ] = ["/TASSO_1983_I181470/d21-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][22.0 ] = ["/TASSO_1983_I181470/d27-x01-y01"]
+analyses["IdentifiedParticle"][321 ]["p" ][29.0 ] = ["/HRS_1987_I215848/d03-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][30.0 ] = ["/TASSO_1980_I153656/d06-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][34.0 ] = ["/TASSO_1983_I181470/d15-x01-y01"]
analyses["IdentifiedParticle"][321 ]["p" ][91.2 ] = ["/DELPHI_1995_I394052/d03-x01-y01","/DELPHI_1998_I473409/d20-x01-y01",
"/OPAL_1994_S2927284/d02-x01-y01"]
# xi
analyses["IdentifiedParticle"][321 ]["xi" ][58.0 ] = ["/TOPAZ_1995_I381900/d02-x01-y02"]
# ratio
analyses["IdentifiedParticle"][321 ]["Ratio"][12.0 ] = ["/TASSO_1980_I153656/d09-x01-y01"]
analyses["IdentifiedParticle"][321 ]["Ratio"][29.0 ] = ["/TPC_1988_I262143/d07-x01-y01","/TPC_1988_I262143/d06-x01-y02"]
analyses["IdentifiedParticle"][321 ]["Ratio"][30.0 ] = ["/TASSO_1980_I153656/d12-x01-y01"]
analyses["IdentifiedParticle"][321 ]["Ratio"][34.0 ] = ["/TASSO_1989_I267755/d02-x01-y01"]
analyses["IdentifiedParticle"][321 ]["Ratio"][44.0 ] = ["/TASSO_1989_I267755/d05-x01-y01"]
analyses["IdentifiedParticle"][321 ]["Ratio"][91.2 ] = ["/DELPHI_1998_I473409/d05-x01-y01","/SLD_1999_S3743934/d02-x01-y01"]
# other
analyses["IdentifiedParticle"][321 ]["Other"][91.2 ] = ["/SLD_1999_S3743934/d30-x01-y01","/SLD_1999_S3743934/d30-x01-y02",
"/SLD_1999_S3743934/d31-x01-y01","/SLD_2004_S5693039/d10-x01-y01",
"/SLD_2004_S5693039/d10-x01-y02","/SLD_2004_S5693039/d10-x01-y03",
"/DELPHI_1995_I382285/a_K","/DELPHI_1995_I382285/d01-x01-y01"]
# K*0
analyses["IdentifiedParticle"][313 ]["x" ][10.0 ] = ["/ARGUS_1993_S2789213/d07-x01-y01","/CLEO_1985_I205668/d10-x01-y01"]
-analyses["IdentifiedParticle"][313 ]["x" ][29.0 ] = ["/TPC_1984_I205869/d03-x01-y01"]
+analyses["IdentifiedParticle"][313 ]["x" ][29.0 ] = ["/TPC_1984_I205869/d03-x01-y01","/HRS_1989_I276948/d02-x01-y01"]
analyses["IdentifiedParticle"][313 ]["x" ][91.2 ] = ["/DELPHI_1996_I420528/d01-x01-y01","/ALEPH_1996_S3486095/d39-x01-y01",
"/OPAL_1997_S3608263/d01-x01-y01","/SLD_1999_S3743934/d08-x01-y01"]
analyses["IdentifiedParticle"][313 ]["Other"][91.2 ] = ["/SLD_1999_S3743934/d28-x01-y01","/SLD_1999_S3743934/d28-x01-y02",
"/SLD_1999_S3743934/d29-x01-y01"]
# K* +/-
analyses["IdentifiedParticle"][323 ]["x" ][10.0 ] = ["/ARGUS_1993_S2789213/d04-x01-y01","/CLEO_1985_I205668/d09-x01-y01"]
analyses["IdentifiedParticle"][323 ]["x" ][14.8 ] = ["/TASSO_1990_I284251/d02-x01-y01"]
analyses["IdentifiedParticle"][323 ]["x" ][21.5 ] = ["/TASSO_1990_I284251/d03-x01-y01"]
+analyses["IdentifiedParticle"][323 ]["x" ][29.0 ] = ["/HRS_1989_I276948/d02-x01-y02"]
analyses["IdentifiedParticle"][323 ]["x" ][34.5 ] = ["/TASSO_1990_I284251/d08-x01-y03"]
analyses["IdentifiedParticle"][323 ]["x" ][35.0 ] = ["/TASSO_1990_I284251/d08-x01-y02","/CELLO_1990_I283026/d02-x01-y01",
"/JADE_1984_I203145/d03-x01-y01"]
analyses["IdentifiedParticle"][323 ]["x" ][42.6 ] = ["/TASSO_1990_I284251/d08-x01-y01"]
analyses["IdentifiedParticle"][323 ]["x" ][91.2 ] = ["/OPAL_1993_I342766/d01-x01-y01","/DELPHI_1995_I377487/d10-x01-y01",
"/ALEPH_1996_S3486095/d43-x01-y01"]
analyses["IdentifiedParticle"][323 ]["Other"][35.0 ] = ["/TASSO_1990_I284251/d10-x01-y01","/TASSO_1990_I284251/d10-x01-y02"]
+# K2*0
+analyses["IdentifiedParticle"][315]["x" ][29. ]=["/HRS_1986_I18688/d01-x01-y03"]
# charm
# D+/-
analyses["IdentifiedParticle"][421 ]["x" ][10.47] = ["/ARGUS_1991_I315059/d03-x01-y01"]
analyses["IdentifiedParticle"][421 ]["x" ][10.5 ] = ["/CLEO_2004_S5809304/d03-x01-y01","/CLEO_2004_S5809304/d04-x01-y01",
"/BELLE_2005_I686014/d03-x01-y01"]
analyses["IdentifiedParticle"][421 ]["x" ][29.0 ] = ["/HRS_1988_I23360/d02-x01-y01"]
+analyses["IdentifiedParticle"][421 ]["x" ][91.2 ] = ["/DELPHI_1993_I356732/d03-x01-y01"]
# D0
analyses["IdentifiedParticle"][411 ]["x" ][10.47] = ["/ARGUS_1991_I315059/d02-x01-y01"]
analyses["IdentifiedParticle"][411 ]["x" ][10.5 ] = ["/CLEO_2004_S5809304/d02-x01-y01","/CLEO_2004_S5809304/d09-x01-y01",
"/BELLE_2005_I686014/d03-x01-y02"]
analyses["IdentifiedParticle"][411 ]["x" ][29.0 ] = ["/HRS_1988_I23360/d02-x01-y02"]
+analyses["IdentifiedParticle"][411 ]["x" ][91.2 ] = ["/DELPHI_1993_I356732/d05-x01-y01"]
# D* 0
analyses["IdentifiedParticle"][423 ]["x" ][10.47] = ["/ARGUS_1991_I315059/d04-x01-y01"]
analyses["IdentifiedParticle"][423 ]["x" ][10.5]=["/CLEO_2004_S5809304/d07-x01-y01","/CLEO_2004_S5809304/d08-x01-y01",
- "/BELLE_2005_I686014/d03-x01-y06","/BELLE_2005_I686014/d03-x01-y07"]
+ "/BELLE_2005_I686014/d03-x01-y05"]
+analyses["IdentifiedParticle"][423 ]["x" ][34.4]=["/JADE_1984_I221004/d01-x01-y01"]
# D* +/-
analyses["IdentifiedParticle"][413 ]["x" ][29.0 ] = ["/TPC_1986_I217416/d01-x01-y01","/TPC_1986_I217416/d01-x01-y02",
- "/HRS_1988_I23360/d01-x01-y01","/HRS_1988_I23360/d01-x01-y02"]
+ "/HRS_1988_I23360/d01-x01-y01","/HRS_1988_I23360/d01-x01-y02",
+ "/MARKII_1982_I177606/d02-x01-y01","/MARKII_1982_I177606/d03-x01-y01"]
analyses["IdentifiedParticle"][413 ]["x" ][34.4 ] = ["/JADE_1984_I202785/d01-x01-y01"]
analyses["IdentifiedParticle"][413 ]["x" ][36.2 ] = ["/TASSO_1989_I278856/d01-x01-y01","/TASSO_1989_I278856/d01-x01-y02",
"/TASSO_1989_I278856/d02-x01-y01","/TASSO_1989_I278856/d02-x01-y02"]
-analyses["IdentifiedParticle"][413 ]["x" ][91.2 ] = ["/ALEPH_1999_S4193598/d01-x01-y01"]
-analyses["IdentifiedParticle"][413 ]["x" ][10.5 ] = ["/CLEO_2004_S5809304/d05-x01-y01","/CLEO_2004_S5809304/d06-x01-y01","/BELLE_2005_I686014/d03-x01-y05"]
+analyses["IdentifiedParticle"][413 ]["x" ][91.2 ] = ["/ALEPH_1999_S4193598/d01-x01-y01","/OPAL_1995_I382219/d03-x01-y01",
+ "/DELPHI_1993_I356732/d01-x01-y01"]
+analyses["IdentifiedParticle"][413 ]["x" ][10.5 ] = ["/CLEO_2004_S5809304/d05-x01-y01","/CLEO_2004_S5809304/d06-x01-y01",
+ "/BELLE_2005_I686014/d03-x01-y06","/BELLE_2005_I686014/d03-x01-y07"]
analyses["IdentifiedParticle"][413 ]["Other"][34.4 ] = ["/JADE_1984_I202785/d03-x01-y01"]
# D_2
analyses["IdentifiedParticle"][425 ]["x" ][10.0 ] = ["/ARGUS_1989_I268577/d02-x01-y01","/ARGUS_1989_I280943/d04-x01-y02"]
analyses["IdentifiedParticle"][425 ]["x" ][10.6 ] = ["/CLEOII_1994_I372349/d01-x01-y01"]
analyses["IdentifiedParticle"][10423]["x" ][10.0 ] = ["/ARGUS_1989_I280943/d04-x01-y01"]
analyses["IdentifiedParticle"][10423]["x" ][10.6 ] = ["/CLEOII_1994_I372349/d01-x01-y02"]
analyses["IdentifiedParticle"][10413]["x" ][10.6 ] = ["/CLEOII_1994_I378319/d04-x01-y02"]
analyses["IdentifiedParticle"][415 ]["x" ][10.6 ] = ["/CLEOII_1994_I378319/d04-x01-y01"]
# D_s+
analyses["IdentifiedParticle"][431 ]["x" ][10.5 ] = ["/CLEO_2000_I526554/d02-x01-y01","/CLEO_2000_I526554/d04-x01-y01"]
analyses["IdentifiedParticle"][431 ]["x" ][10.58] = ["/BABAR_2002_I582184/d03-x01-y02","/BELLE_2005_I686014/d03-x01-y03"]
+analyses["IdentifiedParticle"][431 ]["x" ][29. ] = ["/HRS_1985_I213242/d02-x01-y01"]
+analyses["IdentifiedParticle"][431 ]["x" ][34.7 ] = ["/TASSO_1984_I194774/d01-x01-y01"]
# D_s*+
analyses["IdentifiedParticle"][433 ]["x" ][10.5 ] = ["/CLEO_2000_I526554/d01-x01-y01","/CLEO_2000_I526554/d03-x01-y01"]
analyses["IdentifiedParticle"][433 ]["x" ][10.58] = ["/BABAR_2002_I582184/d04-x01-y02"]
# D_s2
analyses["IdentifiedParticle"][435]["x" ][10.58] = ["/ARGUS_1995_I397794/d02-x01-y01"]
# D_s1(2460)
analyses["IdentifiedParticle"][20433]["x" ][10 ] = ["/BABAR_2006_I714447/d03-x01-y01","/BABAR_2006_I714447/d04-x01-y01"]
# D_s0(2317)
analyses["IdentifiedParticle"][10431]["x" ][10 ] = ["/BABAR_2006_I714447/d02-x01-y01"]
# D_s1(2536)
analyses["IdentifiedParticle"][10433]["x" ][10 ] = ["/ARGUS_1989_I282570/d02-x01-y01"]
analyses["IdentifiedParticle"][10433]["x" ][10.5 ] = ["/CLEOII_1993_I352823/d03-x01-y01"]
# charmonium
analyses["IdentifiedParticle"][443 ]["p" ][10.6 ] = ["/BELLE_2002_I563840/d03-x01-y01","/BELLE_2002_I563840/d03-x01-y02"]
analyses["IdentifiedParticle"][443 ]["x" ][91.2 ] = ["/OPAL_1996_S3257789/d01-x01-y01"]
analyses["IdentifiedParticle"][443 ]["Other"][10.6 ] = ["/BELLE_2002_I563840/d02-x01-y01","/BELLE_2002_I563840/d02-x01-y02",
"/BELLE_2002_I563840/d02-x02-y01","/BELLE_2002_I563840/d02-x02-y02",
"/BELLE_2002_I563840/d02-x03-y01","/BELLE_2002_I563840/d02-x03-y02",
"/BELLE_2002_I563840/d04-x01-y01","/BELLE_2002_I563840/d04-x01-y02",
"/BELLE_2002_I563840/d04-x02-y01","/BELLE_2002_I563840/d04-x02-y02"]
analyses["IdentifiedParticle"][100443]["p" ][10.6 ] = ["/BELLE_2002_I563840/d03-x02-y01"]
# other
analyses["IdentifiedParticle"]["321/2212"]["Ratio"][91.2 ] = ["/DELPHI_1998_I473409/d07-x01-y01"]
#
# Baryons
#
# light unflavoured
# proton
# x
analyses["IdentifiedParticle"][2212]["x" ][3.635] = ["/DASP_1979_I132045/d27-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][4.04 ] = ["/DASP_1979_I132045/d28-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][4.17 ] = ["/DASP_1979_I132045/d29-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][4.30 ] = ["/DASP_1979_I132045/d30-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][4.41 ] = ["/DASP_1979_I132045/d31-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][4.72 ] = ["/DASP_1979_I132045/d32-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][5.0 ] = ["/DASP_1979_I132045/d33-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][5.2 ] = ["/DASP_1979_I132045/d34-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][10.0 ] = ["/ARGUS_1989_I276860/d12-x01-y02","/CLEO_1985_I205668/d03-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][12.0 ] = ["/TASSO_1980_I153656/d04-x01-y02"]
analyses["IdentifiedParticle"][2212]["x" ][14.0 ] = ["/TASSO_1983_I181470/d14-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][22.0 ] = ["/TASSO_1983_I181470/d16-x01-y01"]
-analyses["IdentifiedParticle"][2212]["x" ][29.0 ] = ["/TPC_1988_I262143/d01-x01-y03","/TPC_1988_I262143/d05-x01-y03"]
+analyses["IdentifiedParticle"][2212]["x" ][29.0 ] = ["/TPC_1988_I262143/d01-x01-y03","/TPC_1988_I262143/d05-x01-y03",
+ "/HRS_1987_I215848/d04-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][30.0 ] = ["/TASSO_1980_I153656/d07-x01-y02"]
analyses["IdentifiedParticle"][2212]["x" ][34.0 ] = ["/TASSO_1989_I267755/d09-x01-y01","/TASSO_1983_I181470/d18-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][44.0 ] = ["/TASSO_1989_I267755/d12-x01-y01"]
analyses["IdentifiedParticle"][2212]["x" ][91.2 ] = ["/ALEPH_1995_I382179/d03-x01-y01","/DELPHI_1995_I394052/d06-x01-y01",
"/DELPHI_1998_I473409/d23-x01-y01","/ALEPH_1996_S3486095/d27-x01-y01",
"/SLD_2004_S5693039/d04-x01-y02","/SLD_1999_S3743934/d03-x01-y02"]
# p
analyses["IdentifiedParticle"][2212]["p" ][3.635] = ["/DASP_1979_I132045/d10-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][4.04 ] = ["/DASP_1979_I132045/d11-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][4.17 ] = ["/DASP_1979_I132045/d12-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][4.30 ] = ["/DASP_1979_I132045/d13-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][4.41 ] = ["/DASP_1979_I132045/d14-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][4.72 ] = ["/DASP_1979_I132045/d15-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][5.0 ] = ["/DASP_1979_I132045/d16-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][5.2 ] = ["/DASP_1979_I132045/d17-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][10.0 ] = ["/ARGUS_1989_I276860/d08-x01-y02"]
analyses["IdentifiedParticle"][2212]["p" ][10.54] = ["/BABAR_2013_I1238276/d01-x01-y03","/BABAR_2013_I1238276/d02-x01-y03"]
analyses["IdentifiedParticle"][2212]["p" ][12.0 ] = ["/TASSO_1980_I153656/d04-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][14.0 ] = ["/TASSO_1983_I181470/d23-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][22.0 ] = ["/TASSO_1983_I181470/d11-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][30.0 ] = ["/TASSO_1980_I153656/d07-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][34.0 ] = ["/TASSO_1989_I267755/d03-x01-y01","/JADE_1981_I166363/d01-x01-y01",
"/TASSO_1983_I181470/d17-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][44.0 ] = ["/TASSO_1989_I267755/d06-x01-y01"]
analyses["IdentifiedParticle"][2212]["p" ][91.2 ] = ["/DELPHI_1995_I394052/d04-x01-y01","/DELPHI_1998_I473409/d22-x01-y01",
"/OPAL_1994_S2927284/d03-x01-y01",]
# xi
analyses["IdentifiedParticle"][2212]["xi" ][58.0 ] = ["/TOPAZ_1995_I381900/d02-x01-y03"]
# ratio
analyses["IdentifiedParticle"][2212]["Ratio"][12.0 ] = ["/TASSO_1980_I153656/d10-x01-y01"]
analyses["IdentifiedParticle"][2212]["Ratio"][29.0 ] = ["/TPC_1988_I262143/d06-x01-y03","/TPC_1988_I262143/d07-x01-y02",
"/TPC_1988_I262143/d07-x01-y03"]
analyses["IdentifiedParticle"][2212]["Ratio"][30.0 ] = ["/TASSO_1980_I153656/d13-x01-y01"]
analyses["IdentifiedParticle"][2212]["Ratio"][91.2 ] = ["/SLD_1999_S3743934/d03-x01-y01","/DELPHI_1998_I473409/d06-x01-y01"]
analyses["IdentifiedParticle"][2212]["Other"][91.2 ] = ["/SLD_1999_S3743934/d32-x01-y01","/SLD_1999_S3743934/d32-x01-y02",
"/SLD_1999_S3743934/d33-x01-y01","/SLD_2004_S5693039/d11-x01-y01",
- "/SLD_2004_S5693039/d11-x01-y02","/SLD_2004_S5693039/d11-x01-y03"]
+ "/SLD_2004_S5693039/d11-x01-y02","/SLD_2004_S5693039/d11-x01-y03",
+ "/DELPHI_2000_I531568/d01-x01-y01"]
# Delta++
analyses["IdentifiedParticle"][2224]["x" ][91.2 ] = ["/OPAL_1995_S3198391/d01-x01-y01","/DELPHI_1995_I399737/d01-x01-y01"]
# hyperons
# lambda0
# x
analyses["IdentifiedParticle"][3122]["x" ][10.0 ] = ["/ARGUS_1988_I251097/d05-x01-y01","/ARGUS_1988_I251097/d06-x01-y01"]
analyses["IdentifiedParticle"][3122]["x" ][10.52] = ["/BELLE_2017_I1606201/d01-x01-y01","/CLEO_1985_I205668/d06-x01-y01"]
analyses["IdentifiedParticle"][3122]["x" ][14.0 ] = ["/TASSO_1985_I205119/d04-x01-y01"]
analyses["IdentifiedParticle"][3122]["x" ][22.0 ] = ["/TASSO_1985_I205119/d05-x01-y01"]
-analyses["IdentifiedParticle"][3122]["x" ][29.0 ] = ["/HRS_1992_I339573/d01-x01-y01"]
+analyses["IdentifiedParticle"][3122]["x" ][29.0 ] = ["/HRS_1992_I339573/d01-x01-y01","/MARKII_1985_I209198/d02-x01-y01",
+ "/HRS_1987_I215848/d06-x01-y01","/HRS_1986_I17781/d01-x01-y01"]
analyses["IdentifiedParticle"][3122]["x" ][34.0 ] = ["/TASSO_1985_I205119/d06-x01-y01"]
analyses["IdentifiedParticle"][3122]["x" ][34.8 ] = ["/TASSO_1989_I266893/d08-x01-y01"]
analyses["IdentifiedParticle"][3122]["x" ][42.1 ] = ["/TASSO_1989_I266893/d14-x01-y01"]
analyses["IdentifiedParticle"][3122]["x" ][35.0 ] = ["/CELLO_1990_I283026/d03-x01-y01"]
analyses["IdentifiedParticle"][3122]["x" ][91.2 ] = ["/OPAL_1997_S3396100/d01-x01-y01","/ALEPH_1996_S3486095/d33-x01-y01",
"/DELPHI_1993_I360638/d01-x01-y01","/SLD_1999_S3743934/d07-x01-y01"]
# p
analyses["IdentifiedParticle"][3122]["p" ][14.0 ] = ["/TASSO_1985_I205119/d10-x01-y01"]
analyses["IdentifiedParticle"][3122]["p" ][22.0 ] = ["/TASSO_1985_I205119/d11-x01-y01"]
analyses["IdentifiedParticle"][3122]["p" ][34.0 ] = ["/JADE_1981_I166363/d02-x01-y01","/TASSO_1985_I205119/d12-x01-y01"]
analyses["IdentifiedParticle"][3122]["p" ][34.8 ] = ["/TASSO_1989_I266893/d03-x01-y01"]
analyses["IdentifiedParticle"][3122]["p" ][42.1 ] = ["/TASSO_1989_I266893/d09-x01-y01"]
# xi
analyses["IdentifiedParticle"][3122]["xi" ][91.2 ] = ["/OPAL_1997_S3396100/d02-x01-y01","/ALEPH_2000_I507531/d17-x01-y01",
"/ALEPH_2000_I507531/d19-x01-y01","/ALEPH_2000_I507531/d22-x01-y01",
"/ALEPH_2000_I507531/d23-x01-y01","/ALEPH_2000_I507531/d24-x01-y01",
"/ALEPH_2000_I507531/d25-x01-y01"]
+analyses["IdentifiedParticle"][3122]["xi" ][183. ] =["/DELPHI_2001_I526164/d16-x01-y03"]
+analyses["IdentifiedParticle"][3122]["xi" ][189. ] =["/DELPHI_2001_I526164/d16-x01-y04"]
# other
+analyses["IdentifiedParticle"][3122]["Other"][29.0 ] = ["/MARKII_1985_I209198/d03-x01-y01","/HRS_1986_I17781/d02-x01-y01"]
analyses["IdentifiedParticle"][3122]["Other"][34.8 ] = ["/TASSO_1989_I266893/d04-x01-y01","/TASSO_1989_I266893/d05-x01-y01",
"/TASSO_1989_I266893/d06-x01-y01","/TASSO_1989_I266893/d07-x01-y01",
"/TASSO_1989_I266893/d15-x01-y01","/TASSO_1989_I266893/d15-x01-y02",
"/TASSO_1989_I266893/d15-x01-y03"]
analyses["IdentifiedParticle"][3122]["Other"][42.1 ] = ["/TASSO_1989_I266893/d10-x01-y01","/TASSO_1989_I266893/d11-x01-y01",
"/TASSO_1989_I266893/d12-x01-y01","/TASSO_1989_I266893/d13-x01-y01",
"/TASSO_1989_I266893/d16-x01-y01","/TASSO_1989_I266893/d16-x01-y02",
"/TASSO_1989_I266893/d16-x01-y03"]
analyses["IdentifiedParticle"][3122]["Other"][91.2 ] = ["/DELPHI_1993_I360638/d03-x01-y01","/DELPHI_1993_I360638/d04-x01-y01",
"/DELPHI_1993_I360638/d05-x01-y01","/DELPHI_1993_I360638/d06-x01-y01",
"/SLD_1999_S3743934/d34-x01-y01","/SLD_1999_S3743934/d34-x01-y02",
"/SLD_1999_S3743934/d35-x01-y01","/OPAL_1997_I447188/d03-x01-y01",
"/OPAL_1997_I447188/d03-x01-y02","/OPAL_1997_I447188/d03-x01-y03",
"/OPAL_2000_I474010/d04-x01-y01","/OPAL_2000_I474010/d05-x01-y01",
"/DELPHI_1995_I382285/a_Lam","/DELPHI_1995_I382285/d01-x01-y02",
"/ALEPH_1996_I415745/d03-x01-y01"]
# Sigma+
analyses["IdentifiedParticle"][3222]["x" ][91.2 ] = ["/OPAL_1997_I421977/d01-x01-y01"]
# sigma0
analyses["IdentifiedParticle"][3212]["x" ][10.52] = ["/BELLE_2017_I1606201/d02-x01-y01"]
# sigma-
analyses["IdentifiedParticle"][3112]["x" ][91.2 ] = ["/OPAL_1997_I421977/d02-x01-y01","/DELPHI_2000_I524694/d01-x01-y01"]
# Sigma*+
analyses["IdentifiedParticle"][3224 ]["x" ][10.52] = ["/BELLE_2017_I1606201/d03-x01-y01"]
analyses["IdentifiedParticle"][3224 ]["x" ][91.2 ] = ["/DELPHI_1995_S3137023/d03-x01-y01","/OPAL_1997_S3396100/d05-x01-y01"]
analyses["IdentifiedParticle"][3224 ]["xi" ][91.2 ] = ["/OPAL_1997_S3396100/d06-x01-y01"]
analyses["IdentifiedParticle"]["3224B"]["x" ][91.2 ] = ["/ALEPH_1996_S3486095/d35-x01-y01"]
# sigma*-
analyses["IdentifiedParticle"][3114 ]["x" ][91.2 ] = ["/OPAL_1997_S3396100/d07-x01-y01"]
analyses["IdentifiedParticle"][3114 ]["xi" ][91.2 ] = ["/OPAL_1997_S3396100/d08-x01-y01"]
# xi-
analyses["IdentifiedParticle"][3312]["x" ][10.0 ] = ["/ARGUS_1988_I251097/d09-x01-y01"]
analyses["IdentifiedParticle"][3312]["x" ][10.52] = ["/BELLE_2017_I1606201/d05-x01-y01","/CLEO_1985_I205668/d07-x01-y01"]
+analyses["IdentifiedParticle"][3312]["x" ][29.0 ] = ["/MARKII_1987_I234976/d01-x01-y01"]
analyses["IdentifiedParticle"][3312]["x" ][34.4 ] = ["/TASSO_1983_I192072/d02-x01-y01"]
analyses["IdentifiedParticle"][3312]["x" ][34.8 ] = ["/TASSO_1989_I266893/d23-x01-y01"]
analyses["IdentifiedParticle"][3312]["p" ][34.8 ] = ["/TASSO_1989_I266893/d18-x01-y01"]
analyses["IdentifiedParticle"][3312]["x" ][91.2 ] = ["/OPAL_1997_S3396100/d03-x01-y01","/DELPHI_1995_S3137023/d02-x01-y01",
"/ALEPH_1996_S3486095/d34-x01-y01"]
analyses["IdentifiedParticle"][3312]["xi" ][91.2 ] = ["/OPAL_1997_S3396100/d04-x01-y01","/DELPHI_2006_I719387/d01-x03-y01",]
analyses["IdentifiedParticle"][3312]["Other"][34.8 ] = ["/TASSO_1989_I266893/d19-x01-y01","/TASSO_1989_I266893/d20-x01-y01",
"/TASSO_1989_I266893/d21-x01-y01","/TASSO_1989_I266893/d22-x01-y01"]
# xi*0
analyses["IdentifiedParticle"][3324]["x" ][10.52] = ["/BELLE_2017_I1606201/d07-x01-y01"]
analyses["IdentifiedParticle"][3324]["x" ][91.2 ] = ["/OPAL_1997_S3396100/d09-x01-y01","/ALEPH_1996_S3486095/d36-x01-y01"]
analyses["IdentifiedParticle"][3324]["xi" ][91.2 ] = ["/OPAL_1997_S3396100/d10-x01-y01"]
# omega
analyses["IdentifiedParticle"][3334]["x" ][10.52] = ["/BELLE_2017_I1606201/d06-x01-y01"]
+analyses["IdentifiedParticle"][3334]["x" ][29. ] = ["/MARKII_1987_I247900/d01-x01-y01"]
# lambda 1520
analyses["IdentifiedParticle"][3124]["x" ][10.0 ] = ["/ARGUS_1989_I262415/d04-x01-y01"]
analyses["IdentifiedParticle"][3124]["x" ][10.52] = ["/BELLE_2017_I1606201/d04-x01-y01"]
analyses["IdentifiedParticle"][3124]["x" ][91.2 ] = ["/OPAL_1997_S3396100/d11-x01-y01","/DELPHI_2000_I524694/d03-x01-y01"]
analyses["IdentifiedParticle"][3124]["xi" ][91.2 ] = ["/OPAL_1997_S3396100/d12-x01-y01"]
# charm baryons
# lambda_c
analyses["IdentifiedParticle"][4122 ]["x" ][10.52] = ["/BELLE_2017_I1606201/d08-x01-y01"]
analyses["IdentifiedParticle"][4122 ]["x" ][10.54] = ["/BABAR_2007_S6895344/d01-x01-y01","/BELLE_2005_I686014/d03-x01-y04"]
analyses["IdentifiedParticle"][4122 ]["x" ][10.6 ] = ["/CLEO_1990_I298611/d01-x01-y01","/CLEO_1990_I298611/d02-x01-y01",
"/CLEO_1990_I298611/d03-x01-y01","/CLEO_1990_I298611/d04-x01-y01",
"/CLEO_1990_I298611/d05-x01-y01","/CLEO_1990_I298611/d06-x01-y01"]
analyses["IdentifiedParticle"][4122 ]["Other"][10.5 ] = ["/CLEO_2001_I552541/d03-x01-y01","/CLEO_2001_I552541/d03-x01-y02",
"/CLEO_2001_I552541/d03-x01-y03","/CLEO_2001_I552541/d03-x01-y04",
"/CLEO_2001_I552541/d04-x01-y01","/CLEO_2001_I552541/d04-x01-y02",
"/CLEO_2001_I552541/d04-x01-y03","/CLEO_2001_I552541/d04-x01-y04",]
# sigma_c0
analyses["IdentifiedParticle"][4112 ]["x" ][10.52] = ["/BELLE_2017_I1606201/d11-x01-y01","/CLEOII_1994_I361356/d02-x01-y02"]
analyses["IdentifiedParticle"][4222 ]["x" ][10. ] = ["/ARGUS_1988_I261672/d01-x01-y01","/CLEOII_1994_I361356/d02-x01-y01"]
# sigma_c*0
analyses["IdentifiedParticle"][4114 ]["x" ][10.52] = ["/BELLE_2017_I1606201/d12-x01-y01"]
analyses["IdentifiedParticle"][4224 ]["x" ][10. ] = ["/CLEOII_1997_I424575/d03-x01-y01"]
# xi_c
analyses["IdentifiedParticle"][4132 ]["x" ][10.52] = ["/BELLE_2017_I1606201/d14-x01-y01","/BELLE_2017_I1606201/d15-x01-y01"]
analyses["IdentifiedParticle"][4132 ]["p" ][10.58] = ["/BABAR_2005_S6181155/d02-x01-y02"]
analyses["IdentifiedParticle"][4232 ]["x" ][10.52] = ["/ARGUS_1990_I296522/d02-x01-y01"]
analyses["IdentifiedParticle"][4232 ]["x" ][10.6 ] = ["/CLEOII_1995_I404590/d02-x01-y01"]
# xi_c'
analyses["IdentifiedParticle"][4312 ]["x" ][10.58] = ["/CLEOII_1999_I478217/d01-x01-y01"]
# xi_c*
analyses["IdentifiedParticle"][4314 ]["x" ][10.58] = ["/CLEOII_1995_I397770/d02-x01-y01"]
analyses["IdentifiedParticle"][4324 ]["x" ][10.58] = ["/CLEOII_1996_I416471/d02-x01-y01"]
# omega_c
analyses["IdentifiedParticle"][4332 ]["x" ][10.52] = ["/BELLE_2017_I1606201/d13-x01-y01"]
analyses["IdentifiedParticle"][4332 ]["x" ][10.6] = ["/BABAR_2007_I746745/d01-x01-y01"]
# lambda_c(2595)
analyses["IdentifiedParticle"][14122]["x" ][10.52] = ["/BELLE_2017_I1606201/d09-x01-y01"]
analyses["IdentifiedParticle"][14122]["x" ][10.58] = ["/ARGUS_1993_I357132/d02-x01-y01","/CLEOII_1994_I381696/d05-x01-y01"]
# lambda_c(2625)
analyses["IdentifiedParticle"][4124 ]["x" ][10.52] = ["/BELLE_2017_I1606201/d10-x01-y01"]
analyses["IdentifiedParticle"][4124 ]["x" ][10.58] = ["/ARGUS_1997_I440304/d02-x01-y01","/CLEOII_1994_I381696/d06-x01-y01"]
# b fragmentation
analyses["IdentifiedParticle"][511]["weak" ] = ["/DELPHI_2011_I890503/d01-x01-y01","/SLD_2002_S4869273/d01-x01-y01",
"/ALEPH_2001_S4656318/d01-x01-y01","/OPAL_2003_I599181/d01-x01-y01"]
analyses["IdentifiedParticle"][511]["weak_mean"] = ["/DELPHI_2011_I890503/d02-x01-y01","/ALEPH_2001_S4656318/d07-x01-y01",
"/OPAL_2003_I599181/d02-x01-y01"]
analyses["IdentifiedParticle"][511]["lead" ] = ["/ALEPH_2001_S4656318/d01-x01-y02"]
analyses["IdentifiedParticle"][511]["lead_mean"] = ["/ALEPH_2001_S4656318/d07-x01-y02"]
analyses["IdentifiedParticle"][513]["x"][91.2] = ["/DELPHI_1995_I395026/d04-x01-y01"]
+# deuteron
+analyses["IdentifiedParticle"][1000010020]["p"][10.58] = ["/BABAR_2014_I1286317/d06-x04-y01"]
# multiplcities
analyses["Multiplicity"]["321/2212"][91.2] = ["/DELPHI_1998_I473409/d01-x01-y05"]
# mesons
analyses["Multiplicity"][211 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d01-x01-y01","/CLEO_1985_I205668/d12-x01-y01"]
analyses["Multiplicity"][211 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d01-x01-y02"]
analyses["Multiplicity"][211 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d01-x01-y03","/DELPHI_1996_S3430090/d36-x01-y01",
"/DELPHI_1998_I473409/d01-x01-y02","/SLD_2004_S5693039/d02-x02-y02",
"/SLD_1999_S3743934/d24-x01-y01"]
+analyses["Multiplicity"][211 ][133. ] = ["/DELPHI_2001_I526164/d02-x01-y01"]
analyses["Multiplicity"][211 ][165.0] = ["/PDG_HADRON_MULTIPLICITIES/d01-x01-y04"]
analyses["Multiplicity"][111 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d02-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d02-x01-y01",
"/ARGUS_1990_I278933/d01-x01-y01","/CLEO_1985_I205668/d15-x01-y01",
"/CRYSTAL_BALL_1991_I297905/d01-x01-y01"]
analyses["Multiplicity"][111 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d02-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d02-x01-y02"]
analyses["Multiplicity"][111 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d02-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d02-x01-y03",
"/DELPHI_1996_S3430090/d36-x01-y02","/ALEPH_1996_S3486095/d44-x01-y02"]
analyses["Multiplicity"][321 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d03-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y01",
"/CLEO_1985_I205668/d13-x01-y01"]
analyses["Multiplicity"][321 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d03-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y02"]
analyses["Multiplicity"][321 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d03-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y03",
"/DELPHI_1996_S3430090/d36-x01-y03","/DELPHI_1998_I473409/d01-x01-y03",
"/SLD_2004_S5693039/d03-x02-y02","/SLD_1999_S3743934/d24-x02-y01"]
+analyses["Multiplicity"][321 ][133. ] = ["/DELPHI_2001_I526164/d02-x01-y02"]
analyses["Multiplicity"][321 ][165.0] = ["/PDG_HADRON_MULTIPLICITIES/d03-x01-y04","/PDG_HADRON_MULTIPLICITIES_RATIOS/d03-x01-y04"]
analyses["Multiplicity"][311 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d04-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y01",
"/PLUTO_1981_I165122/d02-x01-y01","/CLEO_1985_I205668/d16-x01-y01"]
analyses["Multiplicity"][311 ][30. ] = ["/TASSO_1990_I284251/d04-x01-y01"]
analyses["Multiplicity"][311 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d04-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y02"]
analyses["Multiplicity"][311 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d04-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y03",
"/DELPHI_1996_S3430090/d36-x01-y04","/ALEPH_1996_S3486095/d44-x01-y05","/SLD_1999_S3743934/d24-x03-y01"]
+analyses["Multiplicity"][311 ][133. ] = ["/DELPHI_2001_I526164/d02-x01-y03"]
analyses["Multiplicity"][311 ][165.0] = ["/PDG_HADRON_MULTIPLICITIES/d04-x01-y04","/PDG_HADRON_MULTIPLICITIES_RATIOS/d04-x01-y04"]
analyses["Multiplicity"][221 ][4. ] = ["/DASP_1979_I132410/d01-x01-y01"]
analyses["Multiplicity"][221 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d05-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d05-x01-y01",
"/ARGUS_1990_I278933/d02-x01-y01","/CRYSTAL_BALL_1991_I297905/d01-x01-y02"]
analyses["Multiplicity"][221 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d05-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d05-x01-y02"]
analyses["Multiplicity"][221 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d05-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d05-x01-y03",
"/DELPHI_1996_S3430090/d36-x01-y05","/ALEPH_1996_S3486095/d44-x01-y03"]
analyses["Multiplicity"][331 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d06-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d06-x01-y01"]
analyses["Multiplicity"][331 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d06-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d06-x01-y02"]
analyses["Multiplicity"][331 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d06-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d06-x01-y03",
"/DELPHI_1996_S3430090/d36-x01-y06","/ALEPH_1996_S3486095/d44-x01-y04"]
analyses["Multiplicity"][411 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d07-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d07-x01-y01"]
analyses["Multiplicity"][411 ][10.47] = ["/ARGUS_1991_I315059/d01-x01-y02"]
analyses["Multiplicity"][411 ][10.58] = ["/CLEO_2004_S5809304/d01-x01-y01","/BELLE_2005_I686014/d02-x01-y02"]
analyses["Multiplicity"][411 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d07-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d07-x01-y02"]
analyses["Multiplicity"][411 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d07-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d07-x01-y03","/DELPHI_1996_S3430090/d36-x01-y07"]
analyses["Multiplicity"][421 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d08-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d08-x01-y01"]
analyses["Multiplicity"][421 ][10.47] = ["/ARGUS_1991_I315059/d01-x01-y01"]
analyses["Multiplicity"][421 ][10.58] = ["/CLEO_2004_S5809304/d01-x01-y02","/CLEO_2004_S5809304/d01-x01-y03","/BELLE_2005_I686014/d02-x01-y01"]
analyses["Multiplicity"][421 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d08-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d08-x01-y02"]
analyses["Multiplicity"][421 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d08-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d08-x01-y03","/DELPHI_1996_S3430090/d36-x01-y08"]
analyses["Multiplicity"][431 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d09-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d09-x01-y01"]
analyses["Multiplicity"][431 ][10.58] = ["/BABAR_2002_I582184/d01-x01-y01","/BELLE_2005_I686014/d02-x01-y03"]
analyses["Multiplicity"][431 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d09-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d09-x01-y02"]
analyses["Multiplicity"][431 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d09-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d09-x01-y03"]
analyses["Multiplicity"][433 ][10.58] = ["/BABAR_2002_I582184/d01-x01-y02"]
analyses["Multiplicity"][413 ][10.47] = ["/ARGUS_1991_I315059/d01-x01-y03"]
analyses["Multiplicity"]["511B"][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d10-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d10-x01-y01","/DELPHI_1996_S3430090/d36-x01-y09"]
analyses["Multiplicity"][521 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d11-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d11-x01-y01"]
analyses["Multiplicity"][531 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d12-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d12-x01-y01"]
analyses["Multiplicity"][9010221][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d13-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d13-x01-y01"]
analyses["Multiplicity"][9010221][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d13-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d13-x01-y02"]
analyses["Multiplicity"][9010221][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d13-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d13-x01-y03","/DELPHI_1996_S3430090/d37-x01-y01"]
analyses["Multiplicity"][9000211][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d14-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d14-x01-y01"]
analyses["Multiplicity"][113 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d15-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d15-x01-y01",
"/ARGUS_1993_S2789213/d01-x01-y02","/CLEO_1985_I205668/d19-x01-y01"]
+analyses["Multiplicity"][113 ][29. ] = ["/HRS_1989_I276948/d03-x01-y01","/HRS_1989_I276948/d03-x01-y03"]
analyses["Multiplicity"][113 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d15-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d15-x01-y02"]
-analyses["Multiplicity"][113 ][34.0 ] = ["/TASSO_1982_I179022/d01-x01-y01"]
analyses["Multiplicity"][113 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d15-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d15-x01-y03",
"/ALEPH_1996_S3486095/d44-x01-y06","/DELPHI_1996_S3430090/d38-x01-y01"]
analyses["Multiplicity"][213 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d16-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d16-x01-y01"]
analyses["Multiplicity"][223 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d17-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d17-x01-y01","/ARGUS_1993_S2789213/d01-x01-y01"]
analyses["Multiplicity"][223 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d17-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d17-x01-y02",
"/ALEPH_1996_S3486095/d44-x01-y07"]
analyses["Multiplicity"][323 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d18-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d18-x01-y01",
"/ARGUS_1993_S2789213/d01-x01-y04","/CLEO_1985_I205668/d20-x01-y01"]
analyses["Multiplicity"][323 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d18-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d18-x01-y02"]
analyses["Multiplicity"][323 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d18-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d18-x01-y03",
"/OPAL_1993_I342766/d02-x01-y01","/DELPHI_1996_S3430090/d38-x01-y02","/ALEPH_1996_S3486095/d44-x01-y09"]
analyses["Multiplicity"][313 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d19-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d19-x01-y01",
"/ARGUS_1993_S2789213/d01-x01-y03","/CLEO_1985_I205668/d21-x01-y01"]
+analyses["Multiplicity"][313 ][29. ] = ["/HRS_1989_I276948/d04-x01-y01","/HRS_1989_I276948/d04-x01-y03"]
analyses["Multiplicity"][313 ][30. ] = ["/TASSO_1990_I284251/d09-x01-y01"]
analyses["Multiplicity"][313 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d19-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d19-x01-y02"]
analyses["Multiplicity"][313 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d19-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d19-x01-y03",
"/DELPHI_1996_S3430090/d38-x01-y03","/ALEPH_1996_S3486095/d44-x01-y10","/SLD_1999_S3743934/d24-x04-y01"]
analyses["Multiplicity"][333 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d20-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d20-x01-y01",
"/ARGUS_1993_S2789213/d01-x01-y05","/CLEO_1985_I205668/d22-x01-y01"]
analyses["Multiplicity"][333 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d20-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d20-x01-y02"]
analyses["Multiplicity"][333 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d20-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d20-x01-y03",
"/DELPHI_1996_S3430090/d38-x01-y04","/ALEPH_1996_S3486095/d44-x01-y08","/SLD_1999_S3743934/d24-x05-y01"]
analyses["Multiplicity"][413 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d21-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d21-x01-y01"]
analyses["Multiplicity"][413 ][10.58] = ["/CLEO_2004_S5809304/d01-x01-y04","/CLEO_2004_S5809304/d01-x01-y05",
"/BELLE_2005_I686014/d02-x01-y06","/BELLE_2005_I686014/d02-x01-y07"]
analyses["Multiplicity"][413 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d21-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d21-x01-y02"]
analyses["Multiplicity"][413 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d21-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d21-x01-y03",
- "/DELPHI_1996_S3430090/d38-x01-y05","/OPAL_1995_I382219/d03-x01-y01"]
+ "/DELPHI_1996_S3430090/d38-x01-y05"]
analyses["Multiplicity"][423 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d22-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d22-x01-y01"]
analyses["Multiplicity"][423 ][10.58] = ["/CLEO_2004_S5809304/d01-x01-y06","/CLEO_2004_S5809304/d01-x01-y07","/BELLE_2005_I686014/d02-x01-y05"]
analyses["Multiplicity"][423 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d22-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d22-x01-y02"]
analyses["Multiplicity"][425 ][10.0 ] = ["/ARGUS_1989_I268577/d01-x01-y01","/ARGUS_1989_I280943/d01-x01-y02",
"/CLEOII_1994_I372349/d03-x01-y01","/CLEOII_1994_I372349/d03-x01-y02"]
analyses["Multiplicity"][10413][10.0 ] = ["/CLEOII_1994_I378319/d05-x01-y03"]
analyses["Multiplicity"][10423][10.0 ] = ["/ARGUS_1989_I280943/d01-x01-y01","/CLEOII_1994_I372349/d03-x01-y03"]
analyses["Multiplicity"][433 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d23-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d23-x01-y01"]
analyses["Multiplicity"][433 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d23-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d23-x01-y02"]
analyses["Multiplicity"][415 ][10. ] = ["/CLEOII_1994_I378319/d05-x01-y01","/CLEOII_1994_I378319/d05-x01-y02"]
analyses["Multiplicity"][513 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d24-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d24-x01-y01",
"/DELPHI_1995_I395026/d02-x01-y01","/ALEPH_1995_I398426/d01-x01-y01",
"/L3_1995_I381046/d01-x01-y01","/OPAL_1996_I428493/d01-x01-y01",
"/DELPHI_1995_I395026/d01-x01-y01"]
analyses["Multiplicity"][443 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d25-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d25-x01-y01"]
analyses["Multiplicity"][443 ][10.6 ] = ["/BABAR_2001_I558091/d01-x01-y01","/BELLE_2002_I563840/d01-x01-y01",
"/BELLE_2002_I563840/d01-x02-y01","/BELLE_2002_I563840/d01-x02-y02"]
analyses["Multiplicity"][443 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d25-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d25-x01-y02",
"/OPAL_1996_S3257789/d02-x01-y01"]
analyses["Multiplicity"][100443 ][10.6 ] = ["/BELLE_2002_I563840/d01-x02-y03"]
analyses["Multiplicity"][100443 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d26-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d26-x01-y01",
"/OPAL_1996_S3257789/d02-x01-y02"]
analyses["Multiplicity"][553 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d27-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d27-x01-y01"]
-analyses["Multiplicity"][20223 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d28-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d28-x01-y01"]
-analyses["Multiplicity"][20333 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d29-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d29-x01-y01"]
+analyses["Multiplicity"][20223 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d28-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d28-x01-y01",
+ "/DELPHI_2003_I628566/d01-x01-y01"]
+analyses["Multiplicity"][20333 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d29-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d29-x01-y01",
+ "/DELPHI_2003_I628566/d01-x01-y02"]
analyses["Multiplicity"][20443 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d30-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d30-x01-y01"]
analyses["Multiplicity"][225 ][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d31-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d31-x01-y01",
"/CLEO_1985_I205668/d23-x01-y01"]
analyses["Multiplicity"][225 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d31-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d31-x01-y02"]
analyses["Multiplicity"][225 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d31-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d31-x01-y03","/DELPHI_1996_S3430090/d39-x01-y01"]
analyses["Multiplicity"][335 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d32-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d32-x01-y01"]
analyses["Multiplicity"][325 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d33-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d33-x01-y01"]
analyses["Multiplicity"][315 ][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d34-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d34-x01-y01"]
analyses["Multiplicity"][315 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d34-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d34-x01-y02","/DELPHI_1996_S3430090/d39-x01-y02"]
analyses["Multiplicity"][515 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d35-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d35-x01-y01"]
analyses["Multiplicity"][10431][10. ] = ["/BABAR_2006_I714447/d01-x01-y01"]
analyses["Multiplicity"][10433][10. ] = ["/BABAR_2006_I714447/d01-x01-y06",
"/ARGUS_1989_I282570/d01-x01-y01","/ARGUS_1989_I282570/d01-x01-y02",
"/CLEOII_1993_I352823/d02-x01-y01",
"/CLEOII_1993_I352823/d02-x01-y02"]
analyses["Multiplicity"][20433][10. ] = ["/BABAR_2006_I714447/d01-x01-y02","/BABAR_2006_I714447/d01-x01-y04","/BABAR_2006_I714447/d01-x01-y05",
"/BABAR_2006_I714447/d01-x01-y03"]
analyses["Multiplicity"][20433][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d36-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d36-x01-y01"]
analyses["Multiplicity"][435 ][10.58] = ["/ARGUS_1995_I397794/d01-x01-y01","/ARGUS_1995_I397794/d01-x02-y01"]
analyses["Multiplicity"][435 ][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d37-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d37-x01-y01"]
#baryons
analyses["Multiplicity"][2212][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d38-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y01",
"/CLEO_1985_I205668/d14-x01-y01"]
analyses["Multiplicity"][2212][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d38-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y02"]
analyses["Multiplicity"][2212][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d38-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y03",
"/DELPHI_1996_S3430090/d40-x01-y01","/DELPHI_1998_I473409/d01-x01-y04",
"/SLD_2004_S5693039/d04-x02-y02","/SLD_1999_S3743934/d24-x06-y01"]
+analyses["Multiplicity"][2212][133. ] = ["/DELPHI_2001_I526164/d02-x01-y04"]
analyses["Multiplicity"][2212][165.0] = ["/PDG_HADRON_MULTIPLICITIES/d38-x01-y04","/PDG_HADRON_MULTIPLICITIES_RATIOS/d38-x01-y04"]
analyses["Multiplicity"][3122][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d39-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y01",
"/ARGUS_1988_I251097/d02-x01-y01","/CLEO_1985_I205668/d17-x01-y01",
"/BELLE_2017_I1606201/d16-x01-y01"]
+analyses["Multiplicity"][3122][29. ] = ["/HRS_1986_I17781/d03-x01-y01"]
analyses["Multiplicity"][3122][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d39-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y02"]
analyses["Multiplicity"][3122][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d39-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y03",
"/DELPHI_1996_S3430090/d40-x01-y02","/ALEPH_1996_S3486095/d44-x01-y11","/DELPHI_1993_I360638/d02-x01-y01",
"/SLD_1999_S3743934/d24-x07-y01",
"/OPAL_2000_I474010/d01-x01-y01","/OPAL_2000_I474010/d01-x01-y02","/OPAL_2000_I474010/d01-x01-y03",
"/OPAL_2000_I474010/d02-x01-y01","/OPAL_2000_I474010/d02-x01-y02","/OPAL_2000_I474010/d02-x01-y03",
"/OPAL_2000_I474010/d03-x01-y01","/OPAL_2000_I474010/d03-x01-y02","/OPAL_2000_I474010/d03-x01-y03"]
+analyses["Multiplicity"][3122][133. ] = ["/DELPHI_2001_I526164/d02-x01-y05"]
analyses["Multiplicity"][3122][165.0] = ["/PDG_HADRON_MULTIPLICITIES/d39-x01-y04","/PDG_HADRON_MULTIPLICITIES_RATIOS/d39-x01-y04"]
analyses["Multiplicity"][3212][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d40-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d40-x01-y01",
"/ARGUS_1988_I251097/d02-x01-y03","/BELLE_2017_I1606201/d16-x01-y02"]
analyses["Multiplicity"][3212][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d40-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d40-x01-y02"]
analyses["Multiplicity"][3112][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d41-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d41-x01-y01"]
analyses["Multiplicity"][3222][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d42-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d42-x01-y01","/ALEPH_1996_S3486095/d44-x01-y12"]
analyses["Multiplicity"][3312][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d44-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d44-x01-y01",
"/ARGUS_1988_I251097/d02-x01-y02","/BELLE_2017_I1606201/d16-x01-y05",
"/CLEO_1985_I205668/d18-x01-y01"]
+analyses["Multiplicity"][3312][29.0 ] = ["/MARKII_1987_I234976/d02-x01-y01","/MARKII_1987_I234976/d02-x01-y02"]
analyses["Multiplicity"][3312][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d44-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d44-x01-y02"]
analyses["Multiplicity"][3312][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d44-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d44-x01-y03",
"/DELPHI_1996_S3430090/d40-x01-y03","/ALEPH_1996_S3486095/d44-x01-y13"]
analyses["Multiplicity"][2224][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d45-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d45-x01-y01",
"/ARGUS_1989_I278932/d02-x01-y02"]
analyses["Multiplicity"][2224][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d45-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d45-x01-y02","/DELPHI_1996_S3430090/d40-x01-y05"]
analyses["Multiplicity"][3114][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d46-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d46-x01-y01","/ARGUS_1988_I251097/d02-x01-y04"]
analyses["Multiplicity"][3114][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d46-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d46-x01-y02"]
analyses["Multiplicity"][3114][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d46-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d46-x01-y03"]
analyses["Multiplicity"][3224][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d47-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d47-x01-y01",
"/ARGUS_1988_I251097/d02-x01-y05","/BELLE_2017_I1606201/d16-x01-y03"]
analyses["Multiplicity"][3224][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d47-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d47-x01-y02"]
analyses["Multiplicity"][3224][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d47-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d47-x01-y03"]
analyses["Multiplicity"][3324][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d49-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d49-x01-y01",
"/ARGUS_1988_I251097/d02-x01-y06","/BELLE_2017_I1606201/d16-x01-y07"]
analyses["Multiplicity"][3324][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d49-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d49-x01-y02",
"/DELPHI_1996_S3430090/d40-x01-y07","/ALEPH_1996_S3486095/d44-x01-y15"]
analyses["Multiplicity"][3334][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d50-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d50-x01-y01",
"/ARGUS_1988_I251097/d02-x01-y07","/BELLE_2017_I1606201/d16-x01-y06"]
+analyses["Multiplicity"][3334][29.0 ] = ["/MARKII_1987_I247900/d02-x01-y01","/MARKII_1987_I247900/d02-x01-y02"]
analyses["Multiplicity"][3334][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d50-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d50-x01-y02"]
analyses["Multiplicity"][3334][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d50-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d50-x01-y03",
"/DELPHI_1996_S3430090/d40-x01-y04","/ALEPH_1996_S3486095/d44-x01-y16"]
analyses["Multiplicity"][4122][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d51-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d51-x01-y01",
"/BABAR_2007_S6895344/d02-x01-y01","/BELLE_2005_I686014/d02-x01-y04","/BELLE_2017_I1606201/d16-x01-y08"]
analyses["Multiplicity"][4122][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d51-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d51-x01-y02"]
analyses["Multiplicity"][4122][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d51-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d51-x01-y03"]
analyses["Multiplicity"][5122][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d52-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d52-x01-y01","/DELPHI_1996_S3430090/d40-x01-y08"]
analyses["Multiplicity"][4222][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d53-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d53-x01-y01"]
analyses["Multiplicity"][3124][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d54-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d54-x01-y01",
"/ARGUS_1989_I262415/d01-x01-y02","/ARGUS_1989_I262415/d01-x02-y02","/BELLE_2017_I1606201/d16-x01-y04"]
analyses["Multiplicity"][3124][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d54-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d54-x01-y02"]
analyses["Multiplicity"][4324][10. ] = ["/CLEOII_1996_I416471/d03-x01-y01"]
analyses["Multiplicity"][4314][10. ] = ["/CLEOII_1995_I397770/d03-x01-y01"]
#
analyses["Multiplicity"]["3222B"][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d43-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d43-x01-y01"]
analyses["Multiplicity"]["3224B"][10. ] = ["/PDG_HADRON_MULTIPLICITIES/d48-x01-y01","/PDG_HADRON_MULTIPLICITIES_RATIOS/d48-x01-y01"]
analyses["Multiplicity"]["3224B"][32.0 ] = ["/PDG_HADRON_MULTIPLICITIES/d48-x01-y02","/PDG_HADRON_MULTIPLICITIES_RATIOS/d48-x01-y02"]
analyses["Multiplicity"]["3224B"][91.2 ] = ["/PDG_HADRON_MULTIPLICITIES/d48-x01-y03","/PDG_HADRON_MULTIPLICITIES_RATIOS/d48-x01-y03",
"/DELPHI_1996_S3430090/d40-x01-y06","/ALEPH_1996_S3486095/d44-x01-y14"]
analyses["Multiplicity"][4132][10.52] = ["/BABAR_2005_S6181155/d03-x01-y01","/ARGUS_1990_I296522/d01-x01-y01",
"/ARGUS_1990_I296522/d01-x01-y02","/ARGUS_1990_I296522/d01-x02-y01",
"/ARGUS_1990_I296522/d01-x02-y02","/BELLE_2017_I1606201/d16-x01-y13","/BELLE_2017_I1606201/d16-x01-y14"]
analyses["Multiplicity"][4232][10.52] = ["/ARGUS_1990_I296522/d01-x01-y03","/ARGUS_1990_I296522/d01-x02-y03"]
analyses["Multiplicity"][14122][10.6] = ["/ARGUS_1993_I357132/d01-x01-y01","/BELLE_2017_I1606201/d16-x01-y09",
"/CLEOII_1994_I381696/d04-x01-y01"]
analyses["Multiplicity"][4124 ][10.6] = ["/ARGUS_1997_I440304/d01-x01-y01","/ARGUS_1997_I440304/d01-x02-y01",
"/BELLE_2017_I1606201/d16-x01-y10","/CLEOII_1994_I381696/d04-x01-y02"]
analyses["Multiplicity"][4332 ][10.] = ["/BELLE_2017_I1606201/d16-x01-y15","/BABAR_2007_I746745/d03-x01-y01"]
analyses["Multiplicity"][4334 ][10.] = ["/BABAR_2006_I724557/d01-x01-y01"]
analyses["Multiplicity"][4212][10.52] = ["/BELLE_2017_I1606201/d16-x01-y11"]
analyses["Multiplicity"][4214][10.52] = ["/BELLE_2017_I1606201/d16-x01-y12"]
+analyses["Multiplicity"][1000010020][10.58] = ["/BABAR_2014_I1286317/d04-x01-y01","/BABAR_2014_I1286317/d05-x01-y01"]
# event shapes
# thrust based
# thrust
analyses["EventShapes"]["T"][9.98 ] = ["/ARGUS_1986_I227324/d02-x01-y02"]
analyses["EventShapes"]["T"][9.5149] = ["/LENA_1981_I164397/d04-x01-y01"]
analyses["EventShapes"]["T"][9.9903] = ["/LENA_1981_I164397/d04-x01-y02"]
-analyses["EventShapes"]["T"][14.0 ] = ["/TASSO_1990_S2148048/d08-x01-y01"]
-analyses["EventShapes"]["T"][22.0 ] = ["/TASSO_1990_S2148048/d08-x01-y02"]
-analyses["EventShapes"]["T"][29.0 ] = ["/HRS_1985_I201482/d03-x01-y01","/HRS_1985_I201482/d04-x01-y01"]
+analyses["EventShapes"]["T"][14.0 ] = ["/TASSO_1990_S2148048/d08-x01-y01","/TASSO_1984_I195333/d13-x01-y01"]
+analyses["EventShapes"]["T"][22.0 ] = ["/TASSO_1990_S2148048/d08-x01-y02","/TASSO_1984_I195333/d13-x01-y02"]
+analyses["EventShapes"]["T"][29.0 ] = ["/HRS_1985_I201482/d03-x01-y01","/HRS_1985_I201482/d04-x01-y01",
+ "/MARKII_1988_I246184/d05-x01-y01",
+ "/MARKII_1988_I246184/d23-x01-y01","/MARKII_1988_I246184/d41-x01-y01"]
+analyses["EventShapes"]["T"][34.0 ] = ["/TASSO_1984_I195333/d13-x01-y03"]
analyses["EventShapes"]["T"][35.0 ] = ["/TASSO_1990_S2148048/d08-x01-y03","/TASSO_1988_I263859/d03-x01-y01",
"/JADE_1998_S3612880/d06-x01-y01"]
+analyses["EventShapes"]["T"][41.4 ] = ["/L3_2004_I652683/d21-x01-y01"]
analyses["EventShapes"]["T"][44.0 ] = ["/TASSO_1990_S2148048/d08-x01-y04","/JADE_1998_S3612880/d02-x01-y01"]
analyses["EventShapes"]["T"][45.0 ] = ["/DELPHI_2003_I620250/d01-x01-y01"]
analyses["EventShapes"]["T"][55.2 ] = ["/AMY_1990_I283337/d12-x01-y01"]
+analyses["EventShapes"]["T"][55.3 ] = ["/L3_2004_I652683/d21-x01-y02"]
analyses["EventShapes"]["T"][58.0 ] = ["/TOPAZ_1993_I361661/d01-x01-y01"]
+analyses["EventShapes"]["T"][65.4 ] = ["/L3_2004_I652683/d21-x01-y03"]
analyses["EventShapes"]["T"][66.0 ] = ["/DELPHI_2003_I620250/d01-x01-y02"]
+analyses["EventShapes"]["T"][75.7 ] = ["/L3_2004_I652683/d22-x01-y01"]
analyses["EventShapes"]["T"][76.0 ] = ["/DELPHI_2003_I620250/d01-x01-y03"]
+analyses["EventShapes"]["T"][82.3 ] = ["/L3_2004_I652683/d22-x01-y02"]
+analyses["EventShapes"]["T"][85.1 ] = ["/L3_2004_I652683/d22-x01-y03"]
analyses["EventShapes"]["T"][91.2 ] = ["/DELPHI_1996_S3430090/d11-x01-y01","/ALEPH_1996_S3486095/d03-x01-y01",
"/OPAL_2004_S6132243/d01-x01-y01","/ALEPH_2004_S5765862/d54-x01-y01",
"/L3_1992_I334954/d01-x01-y01","/DELPHI_2000_I522656/d06-x01-y01",
"/DELPHI_2000_I522656/d33-x01-y01","/DELPHI_2000_I522656/d33-x01-y02","/SLD_1995_I378545/d02-x01-y01"]
analyses["EventShapes"]["T"][130.1] = ["/L3_2004_I652683/d23-x01-y01"]
analyses["EventShapes"]["T"][133.0] = ["/ALEPH_2004_S5765862/d55-x01-y01","/OPAL_2004_S6132243/d01-x01-y02",
"/DELPHI_1999_I499183/d13-x01-y01"]
+analyses["EventShapes"]["T"][136.3] = ["/L3_2004_I652683/d23-x01-y02"]
analyses["EventShapes"]["T"][161.0] = ["/ALEPH_2004_S5765862/d56-x01-y01","/DELPHI_1999_I499183/d13-x01-y02",
"/OPAL_1997_I440721/d03-x01-y01"]
+analyses["EventShapes"]["T"][161.3] = ["/L3_2004_I652683/d23-x01-y03"]
analyses["EventShapes"]["T"][172.0] = ["/ALEPH_2004_S5765862/d57-x01-y01","/DELPHI_1999_I499183/d13-x01-y03",
"/OPAL_2000_I513476/d01-x01-y01"]
+analyses["EventShapes"]["T"][172.3] = ["/L3_2004_I652683/d24-x01-y01"]
analyses["EventShapes"]["T"][177.0] = ["/OPAL_2004_S6132243/d01-x01-y03"]
+analyses["EventShapes"]["T"][182.8] = ["/L3_2004_I652683/d24-x01-y02"]
analyses["EventShapes"]["T"][183.0] = ["/DELPHI_2003_I620250/d38-x01-y01","/ALEPH_2004_S5765862/d58-x01-y01",
"/DELPHI_1999_I499183/d14-x01-y01","/OPAL_2000_I513476/d01-x01-y02"]
+analyses["EventShapes"]["T"][188.6] = ["/L3_2004_I652683/d24-x01-y03"]
analyses["EventShapes"]["T"][189.0] = ["/DELPHI_2003_I620250/d38-x01-y02","/ALEPH_2004_S5765862/d59-x01-y01",
"/OPAL_2000_I513476/d01-x01-y03"]
analyses["EventShapes"]["T"][192.0] = ["/DELPHI_2003_I620250/d38-x01-y03"]
+analyses["EventShapes"]["T"][194.4] = ["/L3_2004_I652683/d25-x01-y01"]
analyses["EventShapes"]["T"][196.0] = ["/DELPHI_2003_I620250/d38-x01-y04"]
+analyses["EventShapes"]["T"][197.0] = ["/OPAL_2004_S6132243/d01-x01-y04","/L3_2008_I825820/d01-x01-y01"]
analyses["EventShapes"]["T"][200.0] = ["/DELPHI_2003_I620250/d39-x01-y01","/ALEPH_2004_S5765862/d60-x01-y01"]
-analyses["EventShapes"]["T"][197.0] = ["/OPAL_2004_S6132243/d01-x01-y04"]
+analyses["EventShapes"]["T"][200.2] = ["/L3_2004_I652683/d25-x01-y02"]
analyses["EventShapes"]["T"][202.0] = ["/DELPHI_2003_I620250/d39-x01-y02"]
analyses["EventShapes"]["T"][205.0] = ["/DELPHI_2003_I620250/d39-x01-y03"]
analyses["EventShapes"]["T"][206.0] = ["/ALEPH_2004_S5765862/d61-x01-y01"]
+analyses["EventShapes"]["T"][206.2] = ["/L3_2004_I652683/d25-x01-y03"]
analyses["EventShapes"]["T"][207.0] = ["/DELPHI_2003_I620250/d39-x01-y04"]
-analyses["EventShapes"]["T"][41.4 ] = ["/L3_2004_I652683/d21-x01-y01"]
-analyses["EventShapes"]["T"][55.3 ] = ["/L3_2004_I652683/d21-x01-y02"]
-analyses["EventShapes"]["T"][65.4 ] = ["/L3_2004_I652683/d21-x01-y03"]
-analyses["EventShapes"]["T"][75.7 ] = ["/L3_2004_I652683/d22-x01-y01"]
-analyses["EventShapes"]["T"][82.3 ] = ["/L3_2004_I652683/d22-x01-y02"]
-analyses["EventShapes"]["T"][85.1 ] = ["/L3_2004_I652683/d22-x01-y03"]
-analyses["EventShapes"]["T"][130.1] = ["/L3_2004_I652683/d23-x01-y01"]
-analyses["EventShapes"]["T"][136.3] = ["/L3_2004_I652683/d23-x01-y02"]
-analyses["EventShapes"]["T"][161.3] = ["/L3_2004_I652683/d23-x01-y03"]
-analyses["EventShapes"]["T"][172.3] = ["/L3_2004_I652683/d24-x01-y01"]
-analyses["EventShapes"]["T"][182.8] = ["/L3_2004_I652683/d24-x01-y02"]
-analyses["EventShapes"]["T"][188.6] = ["/L3_2004_I652683/d24-x01-y03"]
-analyses["EventShapes"]["T"][194.4] = ["/L3_2004_I652683/d25-x01-y01"]
-analyses["EventShapes"]["T"][200.2] = ["/L3_2004_I652683/d25-x01-y02"]
-analyses["EventShapes"]["T"][206.2] = ["/L3_2004_I652683/d25-x01-y03"]
analyses["EventShapes"]["Moment_T"][91.2 ] = ["/OPAL_2004_S6132243/d15-x01-y01"]
analyses["EventShapes"]["Moment_T"][133.0] = ["/OPAL_2004_S6132243/d15-x01-y02"]
analyses["EventShapes"]["Moment_T"][177.0] = ["/OPAL_2004_S6132243/d15-x01-y03"]
analyses["EventShapes"]["Moment_T"][197.0] = ["/OPAL_2004_S6132243/d15-x01-y04"]
analyses["EventShapesFlavour"]["T"][2][91.2] = ["/L3_2004_I652683/d47-x01-y01"]
+analyses["EventShapesFlavour"]["T"][2][197.] = ["/L3_2008_I825820/d01-x01-y02"]
analyses["EventShapesFlavour"]["T"][5][91.2] = ["/L3_2004_I652683/d47-x01-y02"]
+analyses["EventShapesFlavour"]["T"][5][197.] = ["/L3_2008_I825820/d01-x01-y03"]
analyses["EventShapesFlavour"]["HeavyJetMass"][2][91.2] = ["/L3_2004_I652683/d48-x01-y01"]
+analyses["EventShapesFlavour"]["HeavyJetMass"][2][197.] = ["/L3_2008_I825820/d02-x01-y02"]
analyses["EventShapesFlavour"]["HeavyJetMass"][5][91.2] = ["/L3_2004_I652683/d48-x01-y02"]
+analyses["EventShapesFlavour"]["HeavyJetMass"][5][197.] = ["/L3_2008_I825820/d02-x01-y03"]
analyses["EventShapesFlavour"]["BT"][2][91.2] = ["/L3_2004_I652683/d49-x01-y01"]
+analyses["EventShapesFlavour"]["BT"][2][197.] = ["/L3_2008_I825820/d03-x01-y02"]
analyses["EventShapesFlavour"]["BT"][5][91.2] = ["/L3_2004_I652683/d49-x01-y02"]
+analyses["EventShapesFlavour"]["BT"][5][197.] = ["/L3_2008_I825820/d03-x01-y03"]
analyses["EventShapesFlavour"]["BW"][2][91.2] = ["/L3_2004_I652683/d50-x01-y01"]
+analyses["EventShapesFlavour"]["BW"][2][197.] = ["/L3_2008_I825820/d04-x01-y02"]
analyses["EventShapesFlavour"]["BW"][5][91.2] = ["/L3_2004_I652683/d50-x01-y02"]
+analyses["EventShapesFlavour"]["BW"][5][197.] = ["/L3_2008_I825820/d04-x01-y03"]
analyses["EventShapesFlavour"]["C"][2][91.2] = ["/L3_2004_I652683/d51-x01-y01"]
+analyses["EventShapesFlavour"]["C"][2][197.] = ["/L3_2008_I825820/d05-x01-y02"]
analyses["EventShapesFlavour"]["C"][5][91.2] = ["/L3_2004_I652683/d51-x01-y02"]
+analyses["EventShapesFlavour"]["C"][5][197.] = ["/L3_2008_I825820/d05-x01-y03"]
analyses["EventShapesFlavour"]["D"][2][91.2] = ["/L3_2004_I652683/d52-x01-y01"]
analyses["EventShapesFlavour"]["D"][5][91.2] = ["/L3_2004_I652683/d52-x01-y02"]
+analyses["EventShapesFlavour"]["y23"][2][197.] = ["/L3_2008_I825820/d06-x01-y02"]
+analyses["EventShapesFlavour"]["y23"][5][197.] = ["/L3_2008_I825820/d06-x01-y03"]
analyses["EventShapes"]["Moment_H" ][91.2 ] = ["/OPAL_2004_S6132243/d16-x01-y01"]
analyses["EventShapes"]["Moment_H" ][133.0] = ["/OPAL_2004_S6132243/d16-x01-y02"]
analyses["EventShapes"]["Moment_H" ][177.0] = ["/OPAL_2004_S6132243/d16-x01-y03"]
analyses["EventShapes"]["Moment_H" ][197.0] = ["/OPAL_2004_S6132243/d16-x01-y04"]
analyses["EventShapes"]["Moment_C" ][91.2 ] = ["/OPAL_2004_S6132243/d17-x01-y01"]
analyses["EventShapes"]["Moment_C" ][133.0] = ["/OPAL_2004_S6132243/d17-x01-y02"]
analyses["EventShapes"]["Moment_C" ][177.0] = ["/OPAL_2004_S6132243/d17-x01-y03"]
analyses["EventShapes"]["Moment_C" ][197.0] = ["/OPAL_2004_S6132243/d17-x01-y04"]
analyses["EventShapes"]["Moment_BT"][91.2 ] = ["/OPAL_2004_S6132243/d18-x01-y01"]
analyses["EventShapes"]["Moment_BT"][133.0] = ["/OPAL_2004_S6132243/d18-x01-y02"]
analyses["EventShapes"]["Moment_BT"][177.0] = ["/OPAL_2004_S6132243/d18-x01-y03"]
analyses["EventShapes"]["Moment_BT"][197.0] = ["/OPAL_2004_S6132243/d18-x01-y04"]
analyses["EventShapes"]["Moment_BW"][91.2 ] = ["/OPAL_2004_S6132243/d19-x01-y01"]
analyses["EventShapes"]["Moment_BW"][133.0] = ["/OPAL_2004_S6132243/d19-x01-y02"]
analyses["EventShapes"]["Moment_BW"][177.0] = ["/OPAL_2004_S6132243/d19-x01-y03"]
analyses["EventShapes"]["Moment_BW"][197.0] = ["/OPAL_2004_S6132243/d19-x01-y04"]
analyses["EventShapes"]["Moment_y" ][91.2 ] = ["/OPAL_2004_S6132243/d20-x01-y01"]
analyses["EventShapes"]["Moment_y" ][133.0] = ["/OPAL_2004_S6132243/d20-x01-y02"]
analyses["EventShapes"]["Moment_y" ][177.0] = ["/OPAL_2004_S6132243/d20-x01-y03"]
analyses["EventShapes"]["Moment_y" ][197.0] = ["/OPAL_2004_S6132243/d20-x01-y04"]
analyses["EventShapes"]["Moment_M" ][91.2 ] = ["/OPAL_2004_S6132243/d21-x01-y01"]
analyses["EventShapes"]["Moment_M" ][133.0] = ["/OPAL_2004_S6132243/d21-x01-y02"]
analyses["EventShapes"]["Moment_M" ][177.0] = ["/OPAL_2004_S6132243/d21-x01-y03"]
analyses["EventShapes"]["Moment_M" ][197.0] = ["/OPAL_2004_S6132243/d21-x01-y04"]
analyses["EventShapes"]["Moment_m" ][91.2 ] = ["/OPAL_2004_S6132243/d22-x01-y01"]
analyses["EventShapes"]["Moment_m" ][133.0] = ["/OPAL_2004_S6132243/d22-x01-y02"]
analyses["EventShapes"]["Moment_m" ][177.0] = ["/OPAL_2004_S6132243/d22-x01-y03"]
analyses["EventShapes"]["Moment_m" ][197.0] = ["/OPAL_2004_S6132243/d22-x01-y04"]
analyses["EventShapes"]["Moment_S" ][91.2 ] = ["/OPAL_2004_S6132243/d23-x01-y01"]
analyses["EventShapes"]["Moment_S" ][133.0] = ["/OPAL_2004_S6132243/d23-x01-y02"]
analyses["EventShapes"]["Moment_S" ][177.0] = ["/OPAL_2004_S6132243/d23-x01-y03"]
analyses["EventShapes"]["Moment_S" ][197.0] = ["/OPAL_2004_S6132243/d23-x01-y04"]
analyses["EventShapes"]["Moment_O" ][91.2 ] = ["/OPAL_2004_S6132243/d24-x01-y01"]
analyses["EventShapes"]["Moment_O" ][133.0] = ["/OPAL_2004_S6132243/d24-x01-y02"]
analyses["EventShapes"]["Moment_O" ][177.0] = ["/OPAL_2004_S6132243/d24-x01-y03"]
analyses["EventShapes"]["Moment_O" ][197.0] = ["/OPAL_2004_S6132243/d24-x01-y04"]
analyses["EventShapes"]["Moment_L" ][91.2 ] = ["/OPAL_2004_S6132243/d25-x01-y01"]
analyses["EventShapes"]["Moment_L" ][133.0] = ["/OPAL_2004_S6132243/d25-x01-y02"]
analyses["EventShapes"]["Moment_L" ][177.0] = ["/OPAL_2004_S6132243/d25-x01-y03"]
analyses["EventShapes"]["Moment_L" ][197.0] = ["/OPAL_2004_S6132243/d25-x01-y04"]
analyses["EventShapes"]["Moment_BN"][91.2 ] = ["/OPAL_2004_S6132243/d26-x01-y01"]
analyses["EventShapes"]["Moment_BN"][133.0] = ["/OPAL_2004_S6132243/d26-x01-y02"]
analyses["EventShapes"]["Moment_BN"][177.0] = ["/OPAL_2004_S6132243/d26-x01-y03"]
analyses["EventShapes"]["Moment_BN"][197.0] = ["/OPAL_2004_S6132243/d26-x01-y04"]
analyses["EventShapes"]["Major"][45.0 ] = ["/DELPHI_2003_I620250/d02-x01-y01"]
analyses["EventShapes"]["Major"][55.2 ] = ["/AMY_1990_I283337/d13-x01-y01"]
analyses["EventShapes"]["Major"][66.0 ] = ["/DELPHI_2003_I620250/d02-x01-y02"]
analyses["EventShapes"]["Major"][76.0 ] = ["/DELPHI_2003_I620250/d02-x01-y03"]
analyses["EventShapes"]["Major"][91.2 ] = ["/DELPHI_1996_S3430090/d12-x01-y01","/OPAL_2004_S6132243/d07-x01-y01",
- "/ALEPH_2004_S5765862/d94-x01-y01"]
+ "/ALEPH_2004_S5765862/d94-x01-y01","/L3_1992_I334954/d02-x01-y01"]
analyses["EventShapes"]["Major"][133.0] = ["/ALEPH_2004_S5765862/d95-x01-y01","/OPAL_2004_S6132243/d07-x01-y02",
"/DELPHI_1999_I499183/d15-x01-y01"]
analyses["EventShapes"]["Major"][161.0] = ["/ALEPH_2004_S5765862/d96-x01-y01","/DELPHI_1999_I499183/d15-x01-y02",
"/OPAL_1997_I440721/d04-x01-y01"]
analyses["EventShapes"]["Major"][172.0] = ["/ALEPH_2004_S5765862/d97-x01-y01","/DELPHI_1999_I499183/d15-x01-y03",
"/OPAL_2000_I513476/d02-x01-y01"]
analyses["EventShapes"]["Major"][177.0] = ["/OPAL_2004_S6132243/d07-x01-y03"]
analyses["EventShapes"]["Major"][183.0] = ["/DELPHI_2003_I620250/d40-x01-y01","/ALEPH_2004_S5765862/d98-x01-y01",
"/DELPHI_1999_I499183/d16-x01-y01","/OPAL_2000_I513476/d02-x01-y02"]
analyses["EventShapes"]["Major"][189.0] = ["/DELPHI_2003_I620250/d40-x01-y02","/ALEPH_2004_S5765862/d99-x01-y01",
"/OPAL_2000_I513476/d02-x01-y03"]
analyses["EventShapes"]["Major"][192.0] = ["/DELPHI_2003_I620250/d40-x01-y03"]
analyses["EventShapes"]["Major"][196.0] = ["/DELPHI_2003_I620250/d40-x01-y04"]
analyses["EventShapes"]["Major"][197.0] = ["/OPAL_2004_S6132243/d07-x01-y04"]
analyses["EventShapes"]["Major"][200.0] = ["/DELPHI_2003_I620250/d41-x01-y01","/ALEPH_2004_S5765862/d100-x01-y01"]
analyses["EventShapes"]["Major"][202.0] = ["/DELPHI_2003_I620250/d41-x01-y02"]
analyses["EventShapes"]["Major"][205.0] = ["/DELPHI_2003_I620250/d41-x01-y03"]
analyses["EventShapes"]["Major"][206.0] = ["/ALEPH_2004_S5765862/d101-x01-y01"]
analyses["EventShapes"]["Major"][207.0] = ["/DELPHI_2003_I620250/d41-x01-y04"]
+analyses["EventShapes"]["Minor"][29.0 ] = ["/MARKII_1988_I246184/d06-x01-y01",
+ "/MARKII_1988_I246184/d24-x01-y01","/MARKII_1988_I246184/d42-x01-y01"]
analyses["EventShapes"]["Minor"][45.0 ] = ["/DELPHI_2003_I620250/d03-x01-y01"]
analyses["EventShapes"]["Minor"][55.2 ] = ["/AMY_1990_I283337/d14-x01-y01"]
analyses["EventShapes"]["Minor"][66.0 ] = ["/DELPHI_2003_I620250/d03-x01-y02"]
analyses["EventShapes"]["Minor"][76.0 ] = ["/DELPHI_2003_I620250/d03-x01-y03"]
analyses["EventShapes"]["Minor"][91.2 ] = ["/DELPHI_1996_S3430090/d13-x01-y01","/ALEPH_2004_S5765862/d102-x01-y01",
- "/ALEPH_1996_S3486095/d04-x01-y01","/OPAL_2004_S6132243/d08-x01-y01"]
+ "/ALEPH_1996_S3486095/d04-x01-y01","/OPAL_2004_S6132243/d08-x01-y01",
+ "/L3_1992_I334954/d03-x01-y01"]
analyses["EventShapes"]["Minor"][133.0] = ["/ALEPH_2004_S5765862/d103-x01-y01","/OPAL_2004_S6132243/d08-x01-y02",
"/DELPHI_1999_I499183/d17-x01-y01"]
analyses["EventShapes"]["Minor"][161.0] = ["/ALEPH_2004_S5765862/d104-x01-y01","/DELPHI_1999_I499183/d17-x01-y02",
"/OPAL_1997_I440721/d05-x01-y01"]
analyses["EventShapes"]["Minor"][172.0] = ["/ALEPH_2004_S5765862/d105-x01-y01","/DELPHI_1999_I499183/d17-x01-y03",
"/OPAL_2000_I513476/d03-x01-y01"]
analyses["EventShapes"]["Minor"][177.0] = ["/OPAL_2004_S6132243/d08-x01-y03"]
analyses["EventShapes"]["Minor"][183.0] = ["/DELPHI_2003_I620250/d42-x01-y01","/ALEPH_2004_S5765862/d106-x01-y01",
"/DELPHI_1999_I499183/d18-x01-y01","/OPAL_2000_I513476/d03-x01-y02"]
analyses["EventShapes"]["Minor"][189.0] = ["/DELPHI_2003_I620250/d42-x01-y02","/ALEPH_2004_S5765862/d107-x01-y01",
"/OPAL_2000_I513476/d03-x01-y03"]
analyses["EventShapes"]["Minor"][192.0] = ["/DELPHI_2003_I620250/d42-x01-y03"]
analyses["EventShapes"]["Minor"][196.0] = ["/DELPHI_2003_I620250/d42-x01-y04"]
analyses["EventShapes"]["Minor"][197.0] = ["/OPAL_2004_S6132243/d08-x01-y04"]
analyses["EventShapes"]["Minor"][200.0] = ["/DELPHI_2003_I620250/d43-x01-y01","/ALEPH_2004_S5765862/d108-x01-y01"]
analyses["EventShapes"]["Minor"][202.0] = ["/DELPHI_2003_I620250/d43-x01-y02"]
analyses["EventShapes"]["Minor"][205.0] = ["/DELPHI_2003_I620250/d43-x01-y03"]
analyses["EventShapes"]["Minor"][206.0] = ["/ALEPH_2004_S5765862/d109-x01-y01"]
analyses["EventShapes"]["Minor"][207.0] = ["/DELPHI_2003_I620250/d43-x01-y04"]
+analyses["EventShapes"]["O"][29.0 ] = ["/MARKII_1988_I246184/d07-x01-y01",
+ "/MARKII_1988_I246184/d25-x01-y01","/MARKII_1988_I246184/d43-x01-y01"]
analyses["EventShapes"]["O"][45.0 ] = ["/DELPHI_2003_I620250/d06-x01-y01"]
analyses["EventShapes"]["O"][55.2 ] = ["/AMY_1990_I283337/d15-x01-y01"]
analyses["EventShapes"]["O"][66.0 ] = ["/DELPHI_2003_I620250/d06-x01-y02"]
analyses["EventShapes"]["O"][76.0 ] = ["/DELPHI_2003_I620250/d06-x01-y03"]
analyses["EventShapes"]["O"][91.2 ] = ["/ALEPH_2004_S5765862/d133-x01-y01","/DELPHI_1996_S3430090/d14-x01-y01",
"/ALEPH_1996_S3486095/d08-x01-y01","/OPAL_2004_S6132243/d11-x01-y01",
"/L3_1992_I334954/d04-x01-y01","/DELPHI_2000_I522656/d07-x01-y01","/SLD_1995_I378545/d06-x01-y01"]
analyses["EventShapes"]["O"][133.0] = ["/ALEPH_2004_S5765862/d134-x01-y01","/OPAL_2004_S6132243/d11-x01-y02",
"/DELPHI_1999_I499183/d19-x01-y01"]
analyses["EventShapes"]["O"][161.0] = ["/ALEPH_2004_S5765862/d135-x01-y01","/DELPHI_1999_I499183/d19-x01-y02",
"/OPAL_1997_I440721/d06-x01-y01"]
analyses["EventShapes"]["O"][172.0] = ["/ALEPH_2004_S5765862/d136-x01-y01","/DELPHI_1999_I499183/d19-x01-y03",
"/OPAL_2000_I513476/d05-x01-y01"]
analyses["EventShapes"]["O"][177.0] = ["/OPAL_2004_S6132243/d11-x01-y03"]
analyses["EventShapes"]["O"][183.0] = ["/DELPHI_2003_I620250/d44-x01-y01","/ALEPH_2004_S5765862/d137-x01-y01",
"/DELPHI_1999_I499183/d20-x01-y01","/OPAL_2000_I513476/d05-x01-y02"]
analyses["EventShapes"]["O"][189.0] = ["/DELPHI_2003_I620250/d44-x01-y02","/ALEPH_2004_S5765862/d138-x01-y01",
"/OPAL_2000_I513476/d05-x01-y03"]
analyses["EventShapes"]["O"][192.0] = ["/DELPHI_2003_I620250/d44-x01-y03"]
analyses["EventShapes"]["O"][196.0] = ["/DELPHI_2003_I620250/d44-x01-y04"]
analyses["EventShapes"]["O"][197.0] = ["/OPAL_2004_S6132243/d11-x01-y04"]
analyses["EventShapes"]["O"][200.0] = ["/DELPHI_2003_I620250/d45-x01-y01","/ALEPH_2004_S5765862/d139-x01-y01"]
analyses["EventShapes"]["O"][202.0] = ["/DELPHI_2003_I620250/d45-x01-y02"]
analyses["EventShapes"]["O"][205.0] = ["/DELPHI_2003_I620250/d45-x01-y03"]
analyses["EventShapes"]["O"][206.0] = ["/ALEPH_2004_S5765862/d140-x01-y01"]
analyses["EventShapes"]["O"][207.0] = ["/DELPHI_2003_I620250/d45-x01-y04"]
# jet broadenings
# wide
analyses["EventShapes"]["BW"][35.0 ] = ["/JADE_1998_S3612880/d09-x01-y01"]
analyses["EventShapes"]["BW"][41.4 ] = ["/L3_2004_I652683/d36-x01-y01"]
analyses["EventShapes"]["BW"][44.0 ] = ["/JADE_1998_S3612880/d05-x01-y01"]
analyses["EventShapes"]["BW"][45.0 ] = ["/DELPHI_2003_I620250/d13-x01-y01"]
analyses["EventShapes"]["BW"][55.3 ] = ["/L3_2004_I652683/d36-x01-y02"]
analyses["EventShapes"]["BW"][65.4 ] = ["/L3_2004_I652683/d36-x01-y03"]
analyses["EventShapes"]["BW"][66.0 ] = ["/DELPHI_2003_I620250/d13-x01-y02"]
analyses["EventShapes"]["BW"][75.7 ] = ["/L3_2004_I652683/d37-x01-y01"]
analyses["EventShapes"]["BW"][76.0 ] = ["/DELPHI_2003_I620250/d13-x01-y03"]
analyses["EventShapes"]["BW"][82.3 ] = ["/L3_2004_I652683/d37-x01-y02"]
analyses["EventShapes"]["BW"][85.1 ] = ["/L3_2004_I652683/d37-x01-y03"]
analyses["EventShapes"]["BW"][91.2 ] = ["/DELPHI_1996_S3430090/d23-x01-y01","/ALEPH_2004_S5765862/d78-x01-y01",
"/OPAL_2004_S6132243/d05-x01-y01","/DELPHI_2000_I522656/d12-x01-y01","/SLD_1995_I378545/d05-x01-y01"]
analyses["EventShapes"]["BW"][130.1] = ["/L3_2004_I652683/d38-x01-y01"]
analyses["EventShapes"]["BW"][133.0] = ["/OPAL_2004_S6132243/d05-x01-y02","/ALEPH_2004_S5765862/d79-x01-y01",
"/DELPHI_1999_I499183/d33-x01-y01"]
analyses["EventShapes"]["BW"][136.3] = ["/L3_2004_I652683/d38-x01-y02"]
analyses["EventShapes"]["BW"][161.0] = ["/ALEPH_2004_S5765862/d80-x01-y01","/DELPHI_1999_I499183/d33-x01-y02",
"/OPAL_1997_I440721/d12-x01-y01"]
analyses["EventShapes"]["BW"][161.3] = ["/L3_2004_I652683/d38-x01-y03"]
analyses["EventShapes"]["BW"][172.0] = ["/ALEPH_2004_S5765862/d81-x01-y01","/DELPHI_1999_I499183/d33-x01-y03",
"/OPAL_2000_I513476/d10-x01-y01"]
analyses["EventShapes"]["BW"][172.3] = ["/L3_2004_I652683/d39-x01-y01"]
analyses["EventShapes"]["BW"][177.0] = ["/OPAL_2004_S6132243/d05-x01-y03"]
analyses["EventShapes"]["BW"][182.8] = ["/L3_2004_I652683/d39-x01-y02"]
analyses["EventShapes"]["BW"][183.0] = ["/DELPHI_2003_I620250/d46-x01-y01","/ALEPH_2004_S5765862/d82-x01-y01",
"/DELPHI_1999_I499183/d34-x01-y01","/OPAL_2000_I513476/d10-x01-y02"]
analyses["EventShapes"]["BW"][188.6] = ["/L3_2004_I652683/d39-x01-y03"]
analyses["EventShapes"]["BW"][189.0] = ["/DELPHI_2003_I620250/d46-x01-y02","/ALEPH_2004_S5765862/d83-x01-y01",
"/OPAL_2000_I513476/d10-x01-y03"]
analyses["EventShapes"]["BW"][192.0] = ["/DELPHI_2003_I620250/d46-x01-y03"]
analyses["EventShapes"]["BW"][194.4] = ["/L3_2004_I652683/d40-x01-y01"]
analyses["EventShapes"]["BW"][196.0] = ["/DELPHI_2003_I620250/d46-x01-y04"]
-analyses["EventShapes"]["BW"][197.0] = ["/OPAL_2004_S6132243/d05-x01-y04"]
+analyses["EventShapes"]["BW"][197.0] = ["/OPAL_2004_S6132243/d05-x01-y04","/L3_2008_I825820/d04-x01-y01"]
analyses["EventShapes"]["BW"][200.0] = ["/DELPHI_2003_I620250/d47-x01-y01","/ALEPH_2004_S5765862/d84-x01-y01"]
analyses["EventShapes"]["BW"][200.2] = ["/L3_2004_I652683/d40-x01-y02"]
analyses["EventShapes"]["BW"][202.0] = ["/DELPHI_2003_I620250/d47-x01-y02"]
analyses["EventShapes"]["BW"][205.0] = ["/DELPHI_2003_I620250/d47-x01-y03"]
analyses["EventShapes"]["BW"][206.0] = ["/ALEPH_2004_S5765862/d85-x01-y01"]
analyses["EventShapes"]["BW"][206.2] = ["/L3_2004_I652683/d40-x01-y03"]
analyses["EventShapes"]["BW"][207.0] = ["/DELPHI_2003_I620250/d47-x01-y04"]
# narrow
analyses["EventShapes"]["BN"][45.0 ] = ["/DELPHI_2003_I620250/d14-x01-y01"]
analyses["EventShapes"]["BN"][66.0 ] = ["/DELPHI_2003_I620250/d14-x01-y02"]
analyses["EventShapes"]["BN"][76.0 ] = ["/DELPHI_2003_I620250/d14-x01-y03"]
analyses["EventShapes"]["BN"][91.2 ] = ["/DELPHI_1996_S3430090/d24-x01-y01","/OPAL_2004_S6132243/d13-x01-y01"]
analyses["EventShapes"]["BN"][133.0] = ["/OPAL_2004_S6132243/d13-x01-y02","/DELPHI_1999_I499183/d35-x01-y01"]
analyses["EventShapes"]["BN"][161.0] = ["/DELPHI_1999_I499183/d35-x01-y02"]
analyses["EventShapes"]["BN"][172.0] = ["/DELPHI_1999_I499183/d35-x01-y03"]
analyses["EventShapes"]["BN"][177.0] = ["/OPAL_2004_S6132243/d13-x01-y03"]
analyses["EventShapes"]["BN"][183.0] = ["/DELPHI_1999_I499183/d36-x01-y01"]
analyses["EventShapes"]["BN"][197.0] = ["/OPAL_2004_S6132243/d13-x01-y04"]
# total
analyses["EventShapes"]["BT"][35.0 ] = ["/JADE_1998_S3612880/d08-x01-y01"]
analyses["EventShapes"]["BT"][41.4 ] = ["/L3_2004_I652683/d31-x01-y01"]
analyses["EventShapes"]["BT"][44.0 ] = ["/JADE_1998_S3612880/d04-x01-y01"]
analyses["EventShapes"]["BT"][45.0 ] = ["/DELPHI_2003_I620250/d15-x01-y01"]
analyses["EventShapes"]["BT"][55.3 ] = ["/L3_2004_I652683/d31-x01-y02"]
analyses["EventShapes"]["BT"][65.4 ] = ["/L3_2004_I652683/d31-x01-y03"]
analyses["EventShapes"]["BT"][66.0 ] = ["/DELPHI_2003_I620250/d15-x01-y02"]
analyses["EventShapes"]["BT"][75.7 ] = ["/L3_2004_I652683/d32-x01-y01"]
analyses["EventShapes"]["BT"][76.0 ] = ["/DELPHI_2003_I620250/d15-x01-y03"]
analyses["EventShapes"]["BT"][82.3 ] = ["/L3_2004_I652683/d32-x01-y02"]
analyses["EventShapes"]["BT"][85.1 ] = ["/L3_2004_I652683/d32-x01-y03"]
analyses["EventShapes"]["BT"][91.2 ] = ["/DELPHI_1996_S3430090/d25-x01-y01","/OPAL_2004_S6132243/d04-x01-y01",
"/ALEPH_2004_S5765862/d70-x01-y01","/DELPHI_2000_I522656/d13-x01-y01","/SLD_1995_I378545/d04-x01-y01"]
analyses["EventShapes"]["BT"][130.1] = ["/L3_2004_I652683/d33-x01-y01"]
analyses["EventShapes"]["BT"][133.0] = ["/OPAL_2004_S6132243/d04-x01-y02","/ALEPH_2004_S5765862/d71-x01-y01",
"/DELPHI_1999_I499183/d37-x01-y01"]
analyses["EventShapes"]["BT"][136.3] = ["/L3_2004_I652683/d33-x01-y02"]
analyses["EventShapes"]["BT"][161.0] = ["/ALEPH_2004_S5765862/d72-x01-y01","/DELPHI_1999_I499183/d37-x01-y02",
"/OPAL_1997_I440721/d11-x01-y01"]
analyses["EventShapes"]["BT"][161.3] = ["/L3_2004_I652683/d33-x01-y03"]
analyses["EventShapes"]["BT"][172.0] = ["/ALEPH_2004_S5765862/d73-x01-y01","/DELPHI_1999_I499183/d37-x01-y03",
"/OPAL_2000_I513476/d09-x01-y01"]
analyses["EventShapes"]["BT"][172.3] = ["/L3_2004_I652683/d34-x01-y01"]
analyses["EventShapes"]["BT"][177.0] = ["/OPAL_2004_S6132243/d04-x01-y03"]
analyses["EventShapes"]["BT"][182.8] = ["/L3_2004_I652683/d34-x01-y02"]
analyses["EventShapes"]["BT"][183.0] = ["/DELPHI_2003_I620250/d48-x01-y01","/ALEPH_2004_S5765862/d74-x01-y01",
"/DELPHI_1999_I499183/d38-x01-y01","/OPAL_2000_I513476/d09-x01-y02"]
analyses["EventShapes"]["BT"][188.6] = ["/L3_2004_I652683/d34-x01-y03"]
analyses["EventShapes"]["BT"][189.0] = ["/DELPHI_2003_I620250/d48-x01-y02","/ALEPH_2004_S5765862/d75-x01-y01",
"/OPAL_2000_I513476/d09-x01-y03"]
analyses["EventShapes"]["BT"][192.0] = ["/DELPHI_2003_I620250/d48-x01-y03"]
analyses["EventShapes"]["BT"][194.4] = ["/L3_2004_I652683/d35-x01-y01"]
analyses["EventShapes"]["BT"][196.0] = ["/DELPHI_2003_I620250/d48-x01-y04"]
-analyses["EventShapes"]["BT"][197.0] = ["/OPAL_2004_S6132243/d04-x01-y04"]
+analyses["EventShapes"]["BT"][197.0] = ["/OPAL_2004_S6132243/d04-x01-y04","/L3_2008_I825820/d03-x01-y01"]
analyses["EventShapes"]["BT"][200.0] = ["/DELPHI_2003_I620250/d49-x01-y01","/ALEPH_2004_S5765862/d76-x01-y01"]
analyses["EventShapes"]["BT"][200.2] = ["/L3_2004_I652683/d35-x01-y02"]
analyses["EventShapes"]["BT"][202.0] = ["/DELPHI_2003_I620250/d49-x01-y02"]
analyses["EventShapes"]["BT"][205.0] = ["/DELPHI_2003_I620250/d49-x01-y03"]
analyses["EventShapes"]["BT"][206.0] = ["/ALEPH_2004_S5765862/d77-x01-y01"]
analyses["EventShapes"]["BT"][206.2] = ["/L3_2004_I652683/d35-x01-y03"]
analyses["EventShapes"]["BT"][207.0] = ["/DELPHI_2003_I620250/d49-x01-y04"]
# difference
analyses["EventShapes"]["Bdiff"][45.0 ] = ["/DELPHI_2003_I620250/d16-x01-y01"]
analyses["EventShapes"]["Bdiff"][66.0 ] = ["/DELPHI_2003_I620250/d16-x01-y02"]
analyses["EventShapes"]["Bdiff"][76.0 ] = ["/DELPHI_2003_I620250/d16-x01-y03"]
analyses["EventShapes"]["Bdiff"][91.2 ] = ["/DELPHI_1996_S3430090/d26-x01-y01"]
analyses["EventShapes"]["Bdiff"][133.0] = ["/DELPHI_1999_I499183/d39-x01-y01"]
analyses["EventShapes"]["Bdiff"][161.0] = ["/DELPHI_1999_I499183/d39-x01-y02"]
analyses["EventShapes"]["Bdiff"][172.0] = ["/DELPHI_1999_I499183/d39-x01-y03"]
analyses["EventShapes"]["Bdiff"][183.0] = ["/DELPHI_2003_I620250/d50-x01-y01","/DELPHI_1999_I499183/d40-x01-y01"]
analyses["EventShapes"]["Bdiff"][189.0] = ["/DELPHI_2003_I620250/d50-x01-y02"]
analyses["EventShapes"]["Bdiff"][192.0] = ["/DELPHI_2003_I620250/d50-x01-y03"]
analyses["EventShapes"]["Bdiff"][196.0] = ["/DELPHI_2003_I620250/d50-x01-y04"]
analyses["EventShapes"]["Bdiff"][200.0] = ["/DELPHI_2003_I620250/d51-x01-y01"]
analyses["EventShapes"]["Bdiff"][202.0] = ["/DELPHI_2003_I620250/d51-x01-y02"]
analyses["EventShapes"]["Bdiff"][205.0] = ["/DELPHI_2003_I620250/d51-x01-y03"]
analyses["EventShapes"]["Bdiff"][207.0] = ["/DELPHI_2003_I620250/d51-x01-y04"]
# C and D
analyses["EventShapes"]["C"][45.0 ] = ["/DELPHI_2003_I620250/d17-x01-y01"]
analyses["EventShapes"]["C"][66.0 ] = ["/DELPHI_2003_I620250/d17-x01-y02"]
analyses["EventShapes"]["C"][76.0 ] = ["/DELPHI_2003_I620250/d17-x01-y03"]
analyses["EventShapes"]["C"][91.2 ] = ["/DELPHI_1996_S3430090/d18-x01-y01","/ALEPH_1996_S3486095/d07-x01-y01",
"/ALEPH_2004_S5765862/d86-x01-y01","/OPAL_2004_S6132243/d03-x01-y01",
"/L3_1992_I334954/d12-x01-y01","/DELPHI_2000_I522656/d08-x01-y01","/SLD_1995_I378545/d07-x01-y01"]
analyses["EventShapes"]["C"][133.0] = ["/OPAL_2004_S6132243/d03-x01-y02","/ALEPH_2004_S5765862/d87-x01-y01",
"/DELPHI_1999_I499183/d41-x01-y01"]
analyses["EventShapes"]["C"][161.0] = ["/ALEPH_2004_S5765862/d88-x01-y01","/DELPHI_1999_I499183/d41-x01-y02",
"/OPAL_1997_I440721/d09-x01-y01"]
analyses["EventShapes"]["C"][172.0] = ["/ALEPH_2004_S5765862/d89-x01-y01","/DELPHI_1999_I499183/d41-x01-y03",
"/OPAL_2000_I513476/d06-x01-y01"]
analyses["EventShapes"]["C"][177.0] = ["/OPAL_2004_S6132243/d03-x01-y03"]
analyses["EventShapes"]["C"][183.0] = ["/DELPHI_2003_I620250/d52-x01-y01","/ALEPH_2004_S5765862/d90-x01-y01",
"/DELPHI_1999_I499183/d42-x01-y01","/OPAL_2000_I513476/d06-x01-y02"]
analyses["EventShapes"]["C"][189.0] = ["/DELPHI_2003_I620250/d52-x01-y02","/ALEPH_2004_S5765862/d91-x01-y01",
"/OPAL_2000_I513476/d06-x01-y03"]
analyses["EventShapes"]["C"][192.0] = ["/DELPHI_2003_I620250/d52-x01-y03"]
analyses["EventShapes"]["C"][196.0] = ["/DELPHI_2003_I620250/d52-x01-y04"]
-analyses["EventShapes"]["C"][197.0] = ["/OPAL_2004_S6132243/d03-x01-y04"]
+analyses["EventShapes"]["C"][197.0] = ["/OPAL_2004_S6132243/d03-x01-y04","/L3_2008_I825820/d05-x01-y01"]
analyses["EventShapes"]["C"][200.0] = ["/DELPHI_2003_I620250/d53-x01-y01","/ALEPH_2004_S5765862/d92-x01-y01"]
analyses["EventShapes"]["C"][202.0] = ["/DELPHI_2003_I620250/d53-x01-y02"]
analyses["EventShapes"]["C"][205.0] = ["/DELPHI_2003_I620250/d53-x01-y03"]
analyses["EventShapes"]["C"][206.0] = ["/ALEPH_2004_S5765862/d93-x01-y01"]
analyses["EventShapes"]["C"][207.0] = ["/DELPHI_2003_I620250/d53-x01-y04"]
analyses["EventShapes"]["C"][130.1] = ["/L3_2004_I652683/d41-x01-y01"]
analyses["EventShapes"]["C"][136.3] = ["/L3_2004_I652683/d41-x01-y02"]
analyses["EventShapes"]["C"][161.3] = ["/L3_2004_I652683/d41-x01-y03"]
analyses["EventShapes"]["C"][172.3] = ["/L3_2004_I652683/d42-x01-y01"]
analyses["EventShapes"]["C"][182.8] = ["/L3_2004_I652683/d42-x01-y02"]
analyses["EventShapes"]["C"][188.6] = ["/L3_2004_I652683/d42-x01-y03"]
analyses["EventShapes"]["C"][194.4] = ["/L3_2004_I652683/d43-x01-y01"]
analyses["EventShapes"]["C"][200.2] = ["/L3_2004_I652683/d43-x01-y02"]
analyses["EventShapes"]["C"][206.2] = ["/L3_2004_I652683/d43-x01-y03"]
# D parameter
-analyses["EventShapes"]["D"][91.2 ] = ["/DELPHI_1996_S3430090/d19-x01-y01","/OPAL_2004_S6132243/d14-x01-y01"]
+analyses["EventShapes"]["D"][91.2 ] = ["/DELPHI_1996_S3430090/d19-x01-y01","/OPAL_2004_S6132243/d14-x01-y01",
+ "/L3_1992_I334954/d13-x01-y01"]
analyses["EventShapes"]["D"][130.1] = ["/L3_2004_I652683/d44-x01-y01"]
analyses["EventShapes"]["D"][133.0] = ["/OPAL_2004_S6132243/d14-x01-y02","/DELPHI_1999_I499183/d43-x01-y01"]
analyses["EventShapes"]["D"][136.3] = ["/L3_2004_I652683/d44-x01-y02"]
analyses["EventShapes"]["D"][161.0] = ["/DELPHI_1999_I499183/d43-x01-y02"]
analyses["EventShapes"]["D"][161.3] = ["/L3_2004_I652683/d44-x01-y03"]
analyses["EventShapes"]["D"][172.0] = ["/DELPHI_1999_I499183/d43-x01-y03"]
analyses["EventShapes"]["D"][172.3] = ["/L3_2004_I652683/d45-x01-y01"]
analyses["EventShapes"]["D"][177.0] = ["/OPAL_2004_S6132243/d14-x01-y03"]
analyses["EventShapes"]["D"][182.8] = ["/L3_2004_I652683/d45-x01-y02"]
analyses["EventShapes"]["D"][183.0] = ["/DELPHI_2003_I620250/d54-x01-y01","/DELPHI_1999_I499183/d44-x01-y01"]
analyses["EventShapes"]["D"][188.6] = ["/L3_2004_I652683/d45-x01-y03"]
analyses["EventShapes"]["D"][189.0] = ["/DELPHI_2003_I620250/d54-x01-y02"]
analyses["EventShapes"]["D"][192.0] = ["/DELPHI_2003_I620250/d54-x01-y03"]
analyses["EventShapes"]["D"][194.4] = ["/L3_2004_I652683/d46-x01-y01"]
analyses["EventShapes"]["D"][196.0] = ["/DELPHI_2003_I620250/d54-x01-y04"]
analyses["EventShapes"]["D"][197.0] = ["/OPAL_2004_S6132243/d14-x01-y04"]
analyses["EventShapes"]["D"][200.0] = ["/DELPHI_2003_I620250/d55-x01-y01"]
analyses["EventShapes"]["D"][200.2] = ["/L3_2004_I652683/d46-x01-y02"]
analyses["EventShapes"]["D"][202.0] = ["/DELPHI_2003_I620250/d55-x01-y02"]
analyses["EventShapes"]["D"][205.0] = ["/DELPHI_2003_I620250/d55-x01-y03"]
analyses["EventShapes"]["D"][206.2] = ["/L3_2004_I652683/d46-x01-y03"]
analyses["EventShapes"]["D"][207.0] = ["/DELPHI_2003_I620250/d55-x01-y04"]
# hemispheres
# heavy jet mass
analyses["EventShapes"]["HeavyJetMass"][14.0 ] = ["/TASSO_1989_I279165/d02-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][22.0 ] = ["/TASSO_1989_I279165/d02-x01-y02"]
+analyses["EventShapes"]["HeavyJetMass"][29.0 ] = ["/MARKII_1988_I246184/d08-x01-y01",
+ "/MARKII_1988_I246184/d26-x01-y01","/MARKII_1988_I246184/d44-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][34.8 ] = ["/TASSO_1989_I279165/d02-x01-y03"]
analyses["EventShapes"]["HeavyJetMass"][35.0 ] = ["/JADE_1998_S3612880/d07-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][41.4 ] = ["/L3_2004_I652683/d26-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][43.5 ] = ["/TASSO_1989_I279165/d02-x01-y04"]
analyses["EventShapes"]["HeavyJetMass"][44.0 ] = ["/JADE_1998_S3612880/d03-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][45.0 ] = ["/DELPHI_2003_I620250/d07-x01-y01","/DELPHI_2003_I620250/d08-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][55.2 ] = ["/AMY_1990_I283337/d21-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][55.3 ] = ["/L3_2004_I652683/d26-x01-y02"]
analyses["EventShapes"]["HeavyJetMass"][58.0 ] = ["/TOPAZ_1993_I361661/d02-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][65.4 ] = ["/L3_2004_I652683/d26-x01-y03"]
analyses["EventShapes"]["HeavyJetMass"][66.0 ] = ["/DELPHI_2003_I620250/d07-x01-y02","/DELPHI_2003_I620250/d08-x01-y02"]
analyses["EventShapes"]["HeavyJetMass"][75.7 ] = ["/L3_2004_I652683/d27-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][76.0 ] = ["/DELPHI_2003_I620250/d07-x01-y03","/DELPHI_2003_I620250/d08-x01-y03"]
analyses["EventShapes"]["HeavyJetMass"][82.3 ] = ["/L3_2004_I652683/d27-x01-y02"]
analyses["EventShapes"]["HeavyJetMass"][85.1 ] = ["/L3_2004_I652683/d27-x01-y03"]
analyses["EventShapes"]["HeavyJetMass"][91.2 ] = ["/DELPHI_1996_S3430090/d20-x01-y01","/ALEPH_1996_S3486095/d06-x01-y01",
"/OPAL_2004_S6132243/d02-x01-y01","/ALEPH_2004_S5765862/d62-x01-y01",
"/L3_1992_I334954/d14-x01-y01","/DELPHI_2000_I522656/d09-x01-y01","/SLD_1995_I378545/d03-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][130.1] = ["/L3_2004_I652683/d28-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][133.0] = ["/OPAL_2004_S6132243/d02-x01-y02","/ALEPH_2004_S5765862/d63-x01-y01",
"/DELPHI_1999_I499183/d27-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][136.3] = ["/L3_2004_I652683/d28-x01-y02"]
analyses["EventShapes"]["HeavyJetMass"][161.0] = ["/ALEPH_2004_S5765862/d64-x01-y01","/DELPHI_1999_I499183/d27-x01-y02",
"/OPAL_1997_I440721/d10-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][161.3] = ["/L3_2004_I652683/d28-x01-y03"]
analyses["EventShapes"]["HeavyJetMass"][172.0] = ["/ALEPH_2004_S5765862/d65-x01-y01","/DELPHI_1999_I499183/d27-x01-y03",
"/OPAL_2000_I513476/d07-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][172.3] = ["/L3_2004_I652683/d29-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][177.0] = ["/OPAL_2004_S6132243/d02-x01-y03"]
analyses["EventShapes"]["HeavyJetMass"][182.8] = ["/L3_2004_I652683/d29-x01-y02"]
analyses["EventShapes"]["HeavyJetMass"][183.0] = ["/DELPHI_2003_I620250/d56-x01-y01","/DELPHI_2003_I620250/d58-x01-y01",
"/DELPHI_2003_I620250/d60-x01-y01","/ALEPH_2004_S5765862/d66-x01-y01",
"/DELPHI_1999_I499183/d28-x01-y01","/OPAL_2000_I513476/d07-x01-y02"]
analyses["EventShapes"]["HeavyJetMass"][188.6] = ["/L3_2004_I652683/d29-x01-y03"]
analyses["EventShapes"]["HeavyJetMass"][189.0] = ["/DELPHI_2003_I620250/d56-x01-y02","/DELPHI_2003_I620250/d58-x01-y02",
"/DELPHI_2003_I620250/d60-x01-y02","/ALEPH_2004_S5765862/d67-x01-y01",
"/OPAL_2000_I513476/d07-x01-y03"]
analyses["EventShapes"]["HeavyJetMass"][192.0] = ["/DELPHI_2003_I620250/d56-x01-y03","/DELPHI_2003_I620250/d58-x01-y03",
"/DELPHI_2003_I620250/d60-x01-y03"]
analyses["EventShapes"]["HeavyJetMass"][194.4] = ["/L3_2004_I652683/d30-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][196.0] = ["/DELPHI_2003_I620250/d56-x01-y04","/DELPHI_2003_I620250/d58-x01-y04",
"/DELPHI_2003_I620250/d60-x01-y04"]
-analyses["EventShapes"]["HeavyJetMass"][197.0] = ["/OPAL_2004_S6132243/d02-x01-y04"]
+analyses["EventShapes"]["HeavyJetMass"][197.0] = ["/OPAL_2004_S6132243/d02-x01-y04","/L3_2008_I825820/d02-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][200.0] = ["/DELPHI_2003_I620250/d57-x01-y01","/DELPHI_2003_I620250/d59-x01-y01",
"/DELPHI_2003_I620250/d61-x01-y01","/ALEPH_2004_S5765862/d68-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][200.2] = ["/L3_2004_I652683/d30-x01-y02"]
analyses["EventShapes"]["HeavyJetMass"][202.0] = ["/DELPHI_2003_I620250/d57-x01-y02","/DELPHI_2003_I620250/d59-x01-y02",
"/DELPHI_2003_I620250/d61-x01-y02"]
analyses["EventShapes"]["HeavyJetMass"][205.0] = ["/DELPHI_2003_I620250/d57-x01-y03","/DELPHI_2003_I620250/d59-x01-y03",
"/DELPHI_2003_I620250/d61-x01-y03"]
analyses["EventShapes"]["HeavyJetMass"][206.0] = ["/ALEPH_2004_S5765862/d69-x01-y01"]
analyses["EventShapes"]["HeavyJetMass"][206.2] = ["/L3_2004_I652683/d30-x01-y03"]
analyses["EventShapes"]["HeavyJetMass"][207.0] = ["/DELPHI_2003_I620250/d57-x01-y04","/DELPHI_2003_I620250/d59-x01-y04",
"/DELPHI_2003_I620250/d61-x01-y04"]
# jet mass difference
analyses["EventShapes"]["JetMassDifference"][14.0 ] = ["/TASSO_1989_I279165/d01-x01-y01"]
analyses["EventShapes"]["JetMassDifference"][22.0 ] = ["/TASSO_1989_I279165/d01-x01-y02"]
+analyses["EventShapes"]["JetMassDifference"][29.0 ] = ["/MARKII_1988_I246184/d10-x01-y01",
+ "/MARKII_1988_I246184/d28-x01-y01","/MARKII_1988_I246184/d46-x01-y01"]
analyses["EventShapes"]["JetMassDifference"][34.8 ] = ["/TASSO_1989_I279165/d01-x01-y03"]
analyses["EventShapes"]["JetMassDifference"][43.5 ] = ["/TASSO_1989_I279165/d01-x01-y04"]
analyses["EventShapes"]["JetMassDifference"][45.0 ] = ["/DELPHI_2003_I620250/d10-x01-y01"]
analyses["EventShapes"]["JetMassDifference"][55.2 ] = ["/AMY_1990_I283337/d22-x01-y01"]
analyses["EventShapes"]["JetMassDifference"][66.0 ] = ["/DELPHI_2003_I620250/d10-x01-y02"]
analyses["EventShapes"]["JetMassDifference"][76.0 ] = ["/DELPHI_2003_I620250/d10-x01-y03"]
-analyses["EventShapes"]["JetMassDifference"][91.2 ] = ["/DELPHI_1996_S3430090/d22-x01-y01","/ALEPH_2004_S5765862/d110-x01-y01"]
+analyses["EventShapes"]["JetMassDifference"][91.2 ] = ["/DELPHI_1996_S3430090/d22-x01-y01","/ALEPH_2004_S5765862/d110-x01-y01",
+ "/DELPHI_2000_I522656/d11-x01-y01"]
analyses["EventShapes"]["JetMassDifference"][133.0] = ["/ALEPH_2004_S5765862/d111-x01-y01","/DELPHI_1999_I499183/d31-x01-y01"]
analyses["EventShapes"]["JetMassDifference"][161.0] = ["/ALEPH_2004_S5765862/d112-x01-y01","/DELPHI_1999_I499183/d31-x01-y02"]
analyses["EventShapes"]["JetMassDifference"][172.0] = ["/ALEPH_2004_S5765862/d113-x01-y01","/DELPHI_1999_I499183/d31-x01-y03"]
analyses["EventShapes"]["JetMassDifference"][183.0] = ["/DELPHI_2003_I620250/d64-x01-y01","/ALEPH_2004_S5765862/d114-x01-y01",
"/DELPHI_1999_I499183/d32-x01-y01"]
analyses["EventShapes"]["JetMassDifference"][189.0] = ["/DELPHI_2003_I620250/d64-x01-y02","/ALEPH_2004_S5765862/d115-x01-y01"]
analyses["EventShapes"]["JetMassDifference"][192.0] = ["/DELPHI_2003_I620250/d64-x01-y03"]
analyses["EventShapes"]["JetMassDifference"][196.0] = ["/DELPHI_2003_I620250/d64-x01-y04"]
analyses["EventShapes"]["JetMassDifference"][200.0] = ["/DELPHI_2003_I620250/d65-x01-y01","/ALEPH_2004_S5765862/d116-x01-y01"]
analyses["EventShapes"]["JetMassDifference"][202.0] = ["/DELPHI_2003_I620250/d65-x01-y02"]
analyses["EventShapes"]["JetMassDifference"][205.0] = ["/DELPHI_2003_I620250/d65-x01-y03"]
analyses["EventShapes"]["JetMassDifference"][206.0] = ["/ALEPH_2004_S5765862/d117-x01-y01"]
analyses["EventShapes"]["JetMassDifference"][207.0] = ["/DELPHI_2003_I620250/d65-x01-y04"]
# light jet mass
analyses["EventShapes"]["LightJetMass"][14.0 ] = ["/TASSO_1989_I279165/d03-x01-y01"]
analyses["EventShapes"]["LightJetMass"][22.0 ] = ["/TASSO_1989_I279165/d03-x01-y02"]
+analyses["EventShapes"]["LightJetMass"][29.0 ] = ["/MARKII_1988_I246184/d09-x01-y01",
+ "/MARKII_1988_I246184/d27-x01-y01","/MARKII_1988_I246184/d45-x01-y01"]
analyses["EventShapes"]["LightJetMass"][34.8 ] = ["/TASSO_1989_I279165/d03-x01-y03"]
analyses["EventShapes"]["LightJetMass"][43.5 ] = ["/TASSO_1989_I279165/d03-x01-y04"]
analyses["EventShapes"]["LightJetMass"][45.0 ] = ["/DELPHI_2003_I620250/d09-x01-y01"]
analyses["EventShapes"]["LightJetMass"][55.2 ] = ["/AMY_1990_I283337/d20-x01-y01"]
analyses["EventShapes"]["LightJetMass"][66.0 ] = ["/DELPHI_2003_I620250/d09-x01-y02"]
analyses["EventShapes"]["LightJetMass"][76.0 ] = ["/DELPHI_2003_I620250/d09-x01-y03"]
-analyses["EventShapes"]["LightJetMass"][91.2 ] = ["/DELPHI_1996_S3430090/d21-x01-y01","/OPAL_2004_S6132243/d12-x01-y01"]
+analyses["EventShapes"]["LightJetMass"][91.2 ] = ["/DELPHI_1996_S3430090/d21-x01-y01","/OPAL_2004_S6132243/d12-x01-y01",
+ "/L3_1992_I334954/d15-x01-y01"]
analyses["EventShapes"]["LightJetMass"][133.0] = ["/OPAL_2004_S6132243/d12-x01-y02","/DELPHI_1999_I499183/d29-x01-y01"]
analyses["EventShapes"]["LightJetMass"][161.0] = ["/DELPHI_1999_I499183/d29-x01-y02"]
analyses["EventShapes"]["LightJetMass"][172.0] = ["/DELPHI_1999_I499183/d29-x01-y03"]
analyses["EventShapes"]["LightJetMass"][177.0] = ["/OPAL_2004_S6132243/d12-x01-y03"]
analyses["EventShapes"]["LightJetMass"][183.0] = ["/DELPHI_2003_I620250/d62-x01-y01","/DELPHI_1999_I499183/d30-x01-y01"]
analyses["EventShapes"]["LightJetMass"][189.0] = ["/DELPHI_2003_I620250/d62-x01-y02"]
analyses["EventShapes"]["LightJetMass"][192.0] = ["/DELPHI_2003_I620250/d62-x01-y03"]
analyses["EventShapes"]["LightJetMass"][196.0] = ["/DELPHI_2003_I620250/d62-x01-y04"]
analyses["EventShapes"]["LightJetMass"][197.0] = ["/OPAL_2004_S6132243/d12-x01-y04"]
analyses["EventShapes"]["LightJetMass"][200.0] = ["/DELPHI_2003_I620250/d63-x01-y01"]
analyses["EventShapes"]["LightJetMass"][202.0] = ["/DELPHI_2003_I620250/d63-x01-y02"]
analyses["EventShapes"]["LightJetMass"][205.0] = ["/DELPHI_2003_I620250/d63-x01-y03"]
analyses["EventShapes"]["LightJetMass"][207.0] = ["/DELPHI_2003_I620250/d63-x01-y04"]
# total jet mass
analyses["EventShapes"]["TotalJetMass"][45.0 ] = ["/DELPHI_2003_I620250/d11-x01-y01","/DELPHI_2003_I620250/d12-x01-y01"]
analyses["EventShapes"]["TotalJetMass"][66.0 ] = ["/DELPHI_2003_I620250/d11-x01-y02","/DELPHI_2003_I620250/d12-x01-y02"]
analyses["EventShapes"]["TotalJetMass"][76.0 ] = ["/DELPHI_2003_I620250/d11-x01-y03","/DELPHI_2003_I620250/d12-x01-y03"]
+analyses["EventShapes"]["TotalJetMass"][91.2 ] = ["/DELPHI_2000_I522656/d10-x01-y01"]
# jets
# y12
analyses["EventShapes"]["y12_dur"][91.2 ] = ["/ALEPH_2004_S5765862/d149-x01-y01"]
analyses["EventShapes"]["y12_dur"][133.0] = ["/ALEPH_2004_S5765862/d150-x01-y01"]
analyses["EventShapes"]["y12_dur"][161.0] = ["/ALEPH_2004_S5765862/d151-x01-y01"]
analyses["EventShapes"]["y12_dur"][172.0] = ["/ALEPH_2004_S5765862/d152-x01-y01"]
analyses["EventShapes"]["y12_dur"][183.0] = ["/ALEPH_2004_S5765862/d153-x01-y01"]
analyses["EventShapes"]["y12_dur"][189.0] = ["/ALEPH_2004_S5765862/d154-x01-y01"]
analyses["EventShapes"]["y12_dur"][200.0] = ["/ALEPH_2004_S5765862/d155-x01-y01"]
analyses["EventShapes"]["y12_dur"][206.0] = ["/ALEPH_2004_S5765862/d156-x01-y01"]
# y23
analyses["EventShapes"]["y23_dur"][22.0 ] = ["/JADE_1998_S3612880/d12-x01-y01"]
analyses["EventShapes"]["y23_dur"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d24-x01-y01","/JADE_1998_S3612880/d11-x01-y01"]
analyses["EventShapes"]["y23_dur"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d25-x01-y01","/JADE_1998_S3612880/d10-x01-y01"]
analyses["EventShapes"]["y23_dur"][58.0 ] = ["/TOPAZ_1993_I361661/d03-x01-y01"]
analyses["EventShapes"]["y23_dur"][91.2 ] = ["/ALEPH_2004_S5765862/d157-x01-y01","/ALEPH_1996_S3486095/d05-x01-y01",
"/OPAL_2004_S6132243/d06-x01-y01","/JADE_OPAL_2000_S4300807/d26-x01-y01",
- "/DELPHI_1996_S3430090/d27-x01-y01"]
+ "/DELPHI_1996_S3430090/d27-x01-y01","/L3_1992_I334954/d06-x01-y01","/DELPHI_2000_I522656/d18-x01-y01"]
analyses["EventShapes"]["y23_dur"][133.0] = ["/ALEPH_2004_S5765862/d158-x01-y01","/OPAL_2004_S6132243/d06-x01-y02",
"/JADE_OPAL_2000_S4300807/d27-x01-y01"]
analyses["EventShapes"]["y23_dur"][161.0] = ["/ALEPH_2004_S5765862/d159-x01-y01","/JADE_OPAL_2000_S4300807/d28-x01-y01",
"/OPAL_1997_I440721/d20-x01-y01"]
analyses["EventShapes"]["y23_dur"][172.0] = ["/ALEPH_2004_S5765862/d160-x01-y01","/JADE_OPAL_2000_S4300807/d29-x01-y01",
"/OPAL_2000_I513476/d11-x01-y01"]
analyses["EventShapes"]["y23_dur"][177.0] = ["/OPAL_2004_S6132243/d06-x01-y03"]
analyses["EventShapes"]["y23_dur"][183.0] = ["/ALEPH_2004_S5765862/d161-x01-y01","/JADE_OPAL_2000_S4300807/d30-x01-y01",
"/OPAL_2000_I513476/d11-x01-y02"]
analyses["EventShapes"]["y23_dur"][189.0] = ["/ALEPH_2004_S5765862/d162-x01-y01","/JADE_OPAL_2000_S4300807/d31-x01-y01",
"/OPAL_2000_I513476/d11-x01-y03"]
-analyses["EventShapes"]["y23_dur"][197.0] = ["/OPAL_2004_S6132243/d06-x01-y04"]
+analyses["EventShapes"]["y23_dur"][197.0] = ["/OPAL_2004_S6132243/d06-x01-y04","/L3_2008_I825820/d06-x01-y01"]
analyses["EventShapes"]["y23_dur"][200.0] = ["/ALEPH_2004_S5765862/d163-x01-y01"]
analyses["EventShapes"]["y23_dur"][206.0] = ["/ALEPH_2004_S5765862/d164-x01-y01"]
# y34
analyses["EventShapes"]["y34_dur"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d24-x01-y02"]
analyses["EventShapes"]["y34_dur"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d25-x01-y02"]
analyses["EventShapes"]["y34_dur"][91.2 ] = ["/ALEPH_2004_S5765862/d165-x01-y01","/JADE_OPAL_2000_S4300807/d26-x01-y02",
"/DELPHI_1996_S3430090/d29-x01-y01"]
analyses["EventShapes"]["y34_dur"][133.0] = ["/ALEPH_2004_S5765862/d166-x01-y01","/JADE_OPAL_2000_S4300807/d27-x01-y02"]
analyses["EventShapes"]["y34_dur"][161.0] = ["/ALEPH_2004_S5765862/d167-x01-y01","/JADE_OPAL_2000_S4300807/d28-x01-y02"]
analyses["EventShapes"]["y34_dur"][172.0] = ["/ALEPH_2004_S5765862/d168-x01-y01","/JADE_OPAL_2000_S4300807/d29-x01-y02"]
analyses["EventShapes"]["y34_dur"][183.0] = ["/ALEPH_2004_S5765862/d169-x01-y01","/JADE_OPAL_2000_S4300807/d30-x01-y02"]
analyses["EventShapes"]["y34_dur"][189.0] = ["/ALEPH_2004_S5765862/d170-x01-y01","/JADE_OPAL_2000_S4300807/d31-x01-y02"]
analyses["EventShapes"]["y34_dur"][206.0] = ["/ALEPH_2004_S5765862/d172-x01-y01"]
# y45
analyses["EventShapes"]["y45_dur"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d24-x01-y03"]
analyses["EventShapes"]["y45_dur"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d25-x01-y03"]
analyses["EventShapes"]["y45_dur"][91.2 ] = ["/ALEPH_2004_S5765862/d173-x01-y01","/JADE_OPAL_2000_S4300807/d26-x01-y03",
"/DELPHI_1996_S3430090/d31-x01-y01"]
analyses["EventShapes"]["y45_dur"][133.0] = ["/ALEPH_2004_S5765862/d174-x01-y01","/JADE_OPAL_2000_S4300807/d27-x01-y03"]
analyses["EventShapes"]["y45_dur"][161.0] = ["/ALEPH_2004_S5765862/d175-x01-y01","/JADE_OPAL_2000_S4300807/d28-x01-y03"]
analyses["EventShapes"]["y45_dur"][172.0] = ["/ALEPH_2004_S5765862/d176-x01-y01","/JADE_OPAL_2000_S4300807/d29-x01-y03"]
analyses["EventShapes"]["y45_dur"][183.0] = ["/ALEPH_2004_S5765862/d177-x01-y01","/JADE_OPAL_2000_S4300807/d30-x01-y03"]
analyses["EventShapes"]["y45_dur"][189.0] = ["/ALEPH_2004_S5765862/d178-x01-y01","/JADE_OPAL_2000_S4300807/d31-x01-y03"]
analyses["EventShapes"]["y45_dur"][200.0] = ["/ALEPH_2004_S5765862/d179-x01-y01"]
# y56
analyses["EventShapes"]["y56_dur"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d24-x01-y04"]
analyses["EventShapes"]["y56_dur"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d25-x01-y04"]
analyses["EventShapes"]["y56_dur"][91.2 ] = ["/ALEPH_2004_S5765862/d180-x01-y01","/JADE_OPAL_2000_S4300807/d26-x01-y04"]
analyses["EventShapes"]["y56_dur"][133.0] = ["/ALEPH_2004_S5765862/d181-x01-y01","/JADE_OPAL_2000_S4300807/d27-x01-y04"]
analyses["EventShapes"]["y56_dur"][161.0] = ["/ALEPH_2004_S5765862/d182-x01-y01","/JADE_OPAL_2000_S4300807/d28-x01-y04"]
analyses["EventShapes"]["y56_dur"][172.0] = ["/ALEPH_2004_S5765862/d183-x01-y01","/JADE_OPAL_2000_S4300807/d29-x01-y04"]
analyses["EventShapes"]["y56_dur"][183.0] = ["/ALEPH_2004_S5765862/d184-x01-y01","/JADE_OPAL_2000_S4300807/d30-x01-y04"]
analyses["EventShapes"]["y56_dur"][189.0] = ["/ALEPH_2004_S5765862/d185-x01-y01","/JADE_OPAL_2000_S4300807/d31-x01-y04"]
analyses["EventShapes"]["y56_dur"][200.0] = ["/ALEPH_2004_S5765862/d186-x01-y01"]
# jade scheme
analyses["EventShapes"]["y23_jade"][57.7 ] = ["/AMY_1995_I406129/d02-x01-y01","/AMY_1995_I406129/d03-x01-y01",
"/AMY_1995_I406129/d04-x01-y01","/AMY_1995_I406129/d06-x01-y01"]
-analyses["EventShapes"]["y23_jade"][91.2 ] = ["/DELPHI_1996_S3430090/d28-x01-y01"]
+analyses["EventShapes"]["y23_jade"][91.2 ] = ["/DELPHI_1996_S3430090/d28-x01-y01","/L3_1992_I334954/d07-x01-y01","/DELPHI_2000_I522656/d17-x01-y01"]
analyses["EventShapes"]["y34_jade"][91.2 ] = ["/DELPHI_1996_S3430090/d30-x01-y01"]
analyses["EventShapes"]["y45_jade"][91.2 ] = ["/DELPHI_1996_S3430090/d32-x01-y01"]
+analyses["EventShapes"]["y23_cam"][91.2 ] = ["/DELPHI_2000_I522656/d20-x01-y01"]
# jet fractions
# 1 jet
analyses["EventShapes"]["1jet_dur"][91.2 ] = ["/ALEPH_2004_S5765862/d187-x01-y01"]
analyses["EventShapes"]["1jet_dur"][133.0] = ["/ALEPH_2004_S5765862/d188-x01-y01"]
analyses["EventShapes"]["1jet_dur"][161.0] = ["/ALEPH_2004_S5765862/d189-x01-y01"]
analyses["EventShapes"]["1jet_dur"][172.0] = ["/ALEPH_2004_S5765862/d190-x01-y01"]
analyses["EventShapes"]["1jet_dur"][183.0] = ["/ALEPH_2004_S5765862/d191-x01-y01"]
analyses["EventShapes"]["1jet_dur"][189.0] = ["/ALEPH_2004_S5765862/d192-x01-y01"]
analyses["EventShapes"]["1jet_dur"][200.0] = ["/ALEPH_2004_S5765862/d193-x01-y01"]
analyses["EventShapes"]["1jet_dur"][206.0] = ["/ALEPH_2004_S5765862/d194-x01-y01"]
# 2 jet
analyses["EventShapes"]["2jet_dur"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d16-x01-y01"]
analyses["EventShapes"]["2jet_dur"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d17-x01-y01"]
analyses["EventShapes"]["2jet_dur"][91.2 ] = ["/ALEPH_2004_S5765862/d195-x01-y01","/JADE_OPAL_2000_S4300807/d18-x01-y01"]
+analyses["EventShapes"]["2jet_dur"][130.1] = ["/L3_2004_I652683/d10-x01-y01"]
analyses["EventShapes"]["2jet_dur"][133.0] = ["/ALEPH_2004_S5765862/d196-x01-y01","/JADE_OPAL_2000_S4300807/d19-x01-y01"]
+analyses["EventShapes"]["2jet_dur"][136.1] = ["/L3_2004_I652683/d11-x01-y01"]
analyses["EventShapes"]["2jet_dur"][161.0] = ["/ALEPH_2004_S5765862/d197-x01-y01","/JADE_OPAL_2000_S4300807/d20-x01-y01"]
+analyses["EventShapes"]["2jet_dur"][161.3] = ["/L3_2004_I652683/d12-x01-y01"]
analyses["EventShapes"]["2jet_dur"][172.0] = ["/ALEPH_2004_S5765862/d198-x01-y01","/JADE_OPAL_2000_S4300807/d21-x01-y01"]
+analyses["EventShapes"]["2jet_dur"][172.3] = ["/L3_2004_I652683/d13-x01-y01"]
+analyses["EventShapes"]["2jet_dur"][182.8] = ["/L3_2004_I652683/d14-x01-y01"]
analyses["EventShapes"]["2jet_dur"][183.0] = ["/ALEPH_2004_S5765862/d199-x01-y01","/JADE_OPAL_2000_S4300807/d22-x01-y01"]
+analyses["EventShapes"]["2jet_dur"][188.6] = ["/L3_2004_I652683/d15-x01-y01"]
analyses["EventShapes"]["2jet_dur"][189.0] = ["/ALEPH_2004_S5765862/d200-x01-y01","/JADE_OPAL_2000_S4300807/d23-x01-y01"]
+analyses["EventShapes"]["2jet_dur"][194.4] = ["/L3_2004_I652683/d16-x01-y01"]
analyses["EventShapes"]["2jet_dur"][200.0] = ["/ALEPH_2004_S5765862/d201-x01-y01"]
+analyses["EventShapes"]["2jet_dur"][200.2] = ["/L3_2004_I652683/d17-x01-y01"]
analyses["EventShapes"]["2jet_dur"][206.0] = ["/ALEPH_2004_S5765862/d202-x01-y01"]
+analyses["EventShapes"]["2jet_dur"][206.2] = ["/L3_2004_I652683/d18-x01-y01"]
# 3 jet
analyses["EventShapes"]["3jet_dur"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d16-x01-y02"]
analyses["EventShapes"]["3jet_dur"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d17-x01-y02"]
analyses["EventShapes"]["3jet_dur"][91.2 ] = ["/ALEPH_2004_S5765862/d203-x01-y01","/JADE_OPAL_2000_S4300807/d18-x01-y02"]
+analyses["EventShapes"]["3jet_dur"][130.1] = ["/L3_2004_I652683/d10-x01-y02"]
analyses["EventShapes"]["3jet_dur"][133.0] = ["/ALEPH_2004_S5765862/d204-x01-y01","/JADE_OPAL_2000_S4300807/d19-x01-y02"]
+analyses["EventShapes"]["3jet_dur"][136.1] = ["/L3_2004_I652683/d11-x01-y02"]
analyses["EventShapes"]["3jet_dur"][161.0] = ["/ALEPH_2004_S5765862/d205-x01-y01","/JADE_OPAL_2000_S4300807/d20-x01-y02"]
+analyses["EventShapes"]["3jet_dur"][161.3] = ["/L3_2004_I652683/d12-x01-y02"]
analyses["EventShapes"]["3jet_dur"][172.0] = ["/ALEPH_2004_S5765862/d206-x01-y01","/JADE_OPAL_2000_S4300807/d21-x01-y02"]
+analyses["EventShapes"]["3jet_dur"][172.3] = ["/L3_2004_I652683/d13-x01-y02"]
+analyses["EventShapes"]["3jet_dur"][182.8] = ["/L3_2004_I652683/d14-x01-y02"]
analyses["EventShapes"]["3jet_dur"][183.0] = ["/ALEPH_2004_S5765862/d207-x01-y01","/JADE_OPAL_2000_S4300807/d22-x01-y02"]
+analyses["EventShapes"]["3jet_dur"][188.6] = ["/L3_2004_I652683/d15-x01-y02"]
analyses["EventShapes"]["3jet_dur"][189.0] = ["/ALEPH_2004_S5765862/d208-x01-y01","/JADE_OPAL_2000_S4300807/d23-x01-y02"]
+analyses["EventShapes"]["3jet_dur"][194.4] = ["/L3_2004_I652683/d16-x01-y02"]
analyses["EventShapes"]["3jet_dur"][200.0] = ["/ALEPH_2004_S5765862/d209-x01-y01"]
+analyses["EventShapes"]["3jet_dur"][200.2] = ["/L3_2004_I652683/d17-x01-y02"]
analyses["EventShapes"]["3jet_dur"][206.0] = ["/ALEPH_2004_S5765862/d210-x01-y01"]
+analyses["EventShapes"]["3jet_dur"][206.2] = ["/L3_2004_I652683/d18-x01-y02"]
# 4 jet
analyses["EventShapes"]["4jet_dur"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d16-x01-y03"]
analyses["EventShapes"]["4jet_dur"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d17-x01-y03"]
analyses["EventShapes"]["4jet_dur"][91.2 ] = ["/ALEPH_2004_S5765862/d211-x01-y01","/JADE_OPAL_2000_S4300807/d18-x01-y03"]
+analyses["EventShapes"]["4jet_dur"][130.1] = ["/L3_2004_I652683/d10-x01-y03"]
analyses["EventShapes"]["4jet_dur"][133.0] = ["/ALEPH_2004_S5765862/d212-x01-y01","/JADE_OPAL_2000_S4300807/d19-x01-y03"]
+analyses["EventShapes"]["4jet_dur"][136.1] = ["/L3_2004_I652683/d11-x01-y03"]
analyses["EventShapes"]["4jet_dur"][161.0] = ["/ALEPH_2004_S5765862/d213-x01-y01","/JADE_OPAL_2000_S4300807/d20-x01-y03"]
+analyses["EventShapes"]["4jet_dur"][161.3] = ["/L3_2004_I652683/d12-x01-y03"]
analyses["EventShapes"]["4jet_dur"][172.0] = ["/ALEPH_2004_S5765862/d214-x01-y01","/JADE_OPAL_2000_S4300807/d21-x01-y03"]
+analyses["EventShapes"]["4jet_dur"][172.3] = ["/L3_2004_I652683/d13-x01-y03"]
analyses["EventShapes"]["4jet_dur"][183.0] = ["/ALEPH_2004_S5765862/d215-x01-y01","/JADE_OPAL_2000_S4300807/d22-x01-y03"]
+analyses["EventShapes"]["4jet_dur"][182.8] = ["/L3_2004_I652683/d14-x01-y03"]
+analyses["EventShapes"]["4jet_dur"][188.6] = ["/L3_2004_I652683/d15-x01-y03"]
analyses["EventShapes"]["4jet_dur"][189.0] = ["/ALEPH_2004_S5765862/d216-x01-y01","/JADE_OPAL_2000_S4300807/d23-x01-y03"]
+analyses["EventShapes"]["4jet_dur"][194.4] = ["/L3_2004_I652683/d16-x01-y03"]
analyses["EventShapes"]["4jet_dur"][200.0] = ["/ALEPH_2004_S5765862/d217-x01-y01"]
+analyses["EventShapes"]["4jet_dur"][200.2] = ["/L3_2004_I652683/d17-x01-y03"]
analyses["EventShapes"]["4jet_dur"][206.0] = ["/ALEPH_2004_S5765862/d218-x01-y01"]
+analyses["EventShapes"]["4jet_dur"][206.2] = ["/L3_2004_I652683/d18-x01-y03"]
# 5 jet
analyses["EventShapes"]["5jet_dur"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d16-x01-y04"]
analyses["EventShapes"]["5jet_dur"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d17-x01-y04"]
analyses["EventShapes"]["5jet_dur"][91.2 ] = ["/ALEPH_2004_S5765862/d219-x01-y01","/JADE_OPAL_2000_S4300807/d18-x01-y04"]
+analyses["EventShapes"]["5jet_dur"][130.1] = ["/L3_2004_I652683/d10-x01-y04"]
analyses["EventShapes"]["5jet_dur"][133.0] = ["/ALEPH_2004_S5765862/d220-x01-y01","/JADE_OPAL_2000_S4300807/d19-x01-y04"]
+analyses["EventShapes"]["5jet_dur"][136.1] = ["/L3_2004_I652683/d11-x01-y04"]
analyses["EventShapes"]["5jet_dur"][161.0] = ["/ALEPH_2004_S5765862/d221-x01-y01","/JADE_OPAL_2000_S4300807/d20-x01-y04"]
+analyses["EventShapes"]["5jet_dur"][161.3] = ["/L3_2004_I652683/d12-x01-y04"]
analyses["EventShapes"]["5jet_dur"][172.0] = ["/ALEPH_2004_S5765862/d222-x01-y01","/JADE_OPAL_2000_S4300807/d21-x01-y04"]
+analyses["EventShapes"]["5jet_dur"][172.3] = ["/L3_2004_I652683/d13-x01-y04"]
+analyses["EventShapes"]["5jet_dur"][182.8] = ["/L3_2004_I652683/d14-x01-y04"]
analyses["EventShapes"]["5jet_dur"][183.0] = ["/ALEPH_2004_S5765862/d223-x01-y01","/JADE_OPAL_2000_S4300807/d22-x01-y04"]
+analyses["EventShapes"]["5jet_dur"][188.6] = ["/L3_2004_I652683/d15-x01-y04"]
analyses["EventShapes"]["5jet_dur"][189.0] = ["/ALEPH_2004_S5765862/d224-x01-y01","/JADE_OPAL_2000_S4300807/d23-x01-y04"]
+analyses["EventShapes"]["5jet_dur"][194.4] = ["/L3_2004_I652683/d16-x01-y04"]
analyses["EventShapes"]["5jet_dur"][200.0] = ["/ALEPH_2004_S5765862/d225-x01-y01"]
+analyses["EventShapes"]["5jet_dur"][200.2] = ["/L3_2004_I652683/d17-x01-y04"]
analyses["EventShapes"]["5jet_dur"][206.0] = ["/ALEPH_2004_S5765862/d226-x01-y01"]
+analyses["EventShapes"]["5jet_dur"][206.2] = ["/L3_2004_I652683/d18-x01-y04"]
# 6 jet
analyses["EventShapes"]["6jet_dur"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d16-x01-y05"]
analyses["EventShapes"]["6jet_dur"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d17-x01-y05"]
analyses["EventShapes"]["6jet_dur"][91.2 ] = ["/ALEPH_2004_S5765862/d227-x01-y01","/JADE_OPAL_2000_S4300807/d18-x01-y05"]
analyses["EventShapes"]["6jet_dur"][133.0] = ["/ALEPH_2004_S5765862/d228-x01-y01","/JADE_OPAL_2000_S4300807/d19-x01-y05"]
analyses["EventShapes"]["6jet_dur"][161.0] = ["/ALEPH_2004_S5765862/d229-x01-y01","/JADE_OPAL_2000_S4300807/d20-x01-y05"]
analyses["EventShapes"]["6jet_dur"][172.0] = ["/ALEPH_2004_S5765862/d230-x01-y01","/JADE_OPAL_2000_S4300807/d21-x01-y05"]
analyses["EventShapes"]["6jet_dur"][183.0] = ["/ALEPH_2004_S5765862/d231-x01-y01","/JADE_OPAL_2000_S4300807/d22-x01-y05"]
analyses["EventShapes"]["6jet_dur"][189.0] = ["/ALEPH_2004_S5765862/d232-x01-y01","/JADE_OPAL_2000_S4300807/d23-x01-y05"]
analyses["EventShapes"]["6jet_dur"][200.0] = ["/ALEPH_2004_S5765862/d233-x01-y01"]
analyses["EventShapes"]["6jet_dur"][206.0] = ["/ALEPH_2004_S5765862/d234-x01-y01"]
# four jet angles
analyses["FourJet"]["BZ" ][91.2] = ["/OPAL_2001_S4553896/d03-x01-y01"]
analyses["FourJet"]["KSW" ][91.2] = ["/OPAL_2001_S4553896/d04-x01-y01"]
analyses["FourJet"]["NR" ][91.2] = ["/OPAL_2001_S4553896/d05-x01-y01"]
analyses["FourJet"]["alpha34"][91.2] = ["/OPAL_2001_S4553896/d06-x01-y01"]
# Jet cone energy fraction
analyses["EventShapes"]["JCEF" ][91.2] = ["/DELPHI_2000_I522656/d05-x01-y01",
"/DELPHI_2000_I522656/d29-x01-y01","/DELPHI_2000_I522656/d29-x01-y02",
"/DELPHI_2000_I522656/d30-x01-y01","/DELPHI_2000_I522656/d30-x01-y02",
"/DELPHI_2000_I522656/d31-x01-y01","/DELPHI_2000_I522656/d31-x01-y02",
"/DELPHI_2000_I522656/d32-x01-y01","/DELPHI_2000_I522656/d32-x01-y02",
"/SLD_1995_I378545/d16-x01-y01"]
# EEC
analyses["EventShapes"]["EEC" ][7.7 ] = ["/PLUTO_1981_I156315/d01-x01-y01"]
analyses["EventShapes"]["EEC" ][9.4 ] = ["/PLUTO_1981_I156315/d01-x01-y02"]
analyses["EventShapes"]["EEC" ][12.0] = ["/PLUTO_1981_I156315/d01-x01-y03"]
analyses["EventShapes"]["EEC" ][13.0] = ["/PLUTO_1981_I156315/d01-x01-y04"]
analyses["EventShapes"]["EEC" ][14.0] = ["/TASSO_1987_I248660/d01-x01-y01","/JADE_1984_I202784/d01-x01-y01"]
analyses["EventShapes"]["EEC" ][17.0] = ["/PLUTO_1981_I156315/d01-x01-y05"]
analyses["EventShapes"]["EEC" ][22.0] = ["/TASSO_1987_I248660/d02-x01-y01","/JADE_1984_I202784/d01-x01-y02",
"/CELLO_1982_I12010/d01-x01-y01","/PLUTO_1981_I156315/d01-x01-y06"]
analyses["EventShapes"]["EEC" ][27.6] = ["/PLUTO_1981_I156315/d01-x01-y07"]
-analyses["EventShapes"]["EEC" ][29.0] = ["/MAC_1985_I202924/d01-x01-y01","/MAC_1985_I202924/d01-x01-y02"]
+analyses["EventShapes"]["EEC" ][29.0] = ["/MAC_1985_I202924/d01-x01-y01","/MAC_1985_I202924/d01-x01-y02",
+ "/MARKII_1988_I250899/d01-x01-y01","/MARKII_1988_I250899/d03-x01-y01","/MARKII_1988_I250899/d05-x01-y01"]
analyses["EventShapes"]["EEC" ][30.8] = ["/PLUTO_1981_I156315/d01-x01-y08"]
analyses["EventShapes"]["EEC" ][34.0] = ["/JADE_1984_I202784/d01-x01-y03","/CELLO_1982_I12010/d01-x01-y02"]
analyses["EventShapes"]["EEC" ][34.6] = ["/PLUTO_1985_I215869/d01-x01-y01"]
analyses["EventShapes"]["EEC" ][34.8] = ["/TASSO_1987_I248660/d03-x01-y01"]
analyses["EventShapes"]["EEC" ][43.5] = ["/TASSO_1987_I248660/d04-x01-y01"]
analyses["EventShapes"]["EEC" ][53.3] = ["/TOPAZ_1989_I279575/d01-x01-y01","/TOPAZ_1989_I279575/d01-x01-y02"]
analyses["EventShapes"]["EEC" ][91.2] = ["/DELPHI_1996_S3430090/d33-x01-y01","/DELPHI_2000_I522656/d03-x01-y01",
"/DELPHI_2000_I522656/d21-x01-y01","/DELPHI_2000_I522656/d21-x01-y02",
"/DELPHI_2000_I522656/d22-x01-y01","/DELPHI_2000_I522656/d22-x01-y02",
"/DELPHI_2000_I522656/d23-x01-y01","/DELPHI_2000_I522656/d23-x01-y02",
"/DELPHI_2000_I522656/d24-x01-y01","/DELPHI_2000_I522656/d24-x01-y02",
"/SLD_1995_I378545/d14-x01-y01"]
analyses["EventShapes"]["EEC" ][59.5] = ["/TOPAZ_1989_I279575/d02-x01-y01","/TOPAZ_1989_I279575/d02-x01-y02"]
# AEEC
analyses["EventShapes"]["AEEC"][8.65] = ["/PLUTO_1981_I156315/d04-x01-y01"]
analyses["EventShapes"]["AEEC"][14.0] = ["/JADE_1984_I202784/d02-x01-y01"]
analyses["EventShapes"]["AEEC"][22.0] = ["/JADE_1984_I202784/d02-x01-y02","/CELLO_1982_I12010/d03-x01-y01"]
-analyses["EventShapes"]["AEEC"][29.0] = ["/MAC_1985_I202924/d01-x01-y03"]
+analyses["EventShapes"]["AEEC"][29.0] = ["/MAC_1985_I202924/d01-x01-y03","/MARKII_1988_I250899/d02-x01-y01",
+ "/MARKII_1988_I250899/d04-x01-y01","/MARKII_1988_I250899/d06-x01-y01"]
analyses["EventShapes"]["AEEC"][30.8] = ["/PLUTO_1981_I156315/d05-x01-y01"]
analyses["EventShapes"]["AEEC"][34.0] = ["/JADE_1984_I202784/d02-x01-y03","/CELLO_1982_I12010/d03-x01-y02"]
analyses["EventShapes"]["AEEC"][53.3] = ["/TOPAZ_1989_I279575/d01-x01-y03"]
analyses["EventShapes"]["AEEC"][59.5] = ["/TOPAZ_1989_I279575/d02-x01-y03"]
analyses["EventShapes"]["AEEC"][91.2] = ["/DELPHI_1996_S3430090/d34-x01-y01","/DELPHI_2000_I522656/d04-x01-y01",
"/DELPHI_2000_I522656/d25-x01-y01","/DELPHI_2000_I522656/d25-x01-y02",
"/DELPHI_2000_I522656/d26-x01-y01","/DELPHI_2000_I522656/d26-x01-y02",
"/DELPHI_2000_I522656/d27-x01-y01","/DELPHI_2000_I522656/d27-x01-y02",
"/DELPHI_2000_I522656/d28-x01-y01","/DELPHI_2000_I522656/d28-x01-y02",
"/SLD_1995_I378545/d15-x01-y01"]
# sphericity based
analyses["EventShapes"]["S"][9.98 ] = ["/ARGUS_1986_I227324/d01-x01-y02"]
analyses["EventShapes"]["S"][12.0 ] = ["/TASSO_1980_I153511/d01-x01-y01"]
-analyses["EventShapes"]["S"][14.0 ] = ["/TASSO_1990_S2148048/d06-x01-y01"]
-analyses["EventShapes"]["S"][22.0 ] = ["/TASSO_1990_S2148048/d06-x01-y02"]
-analyses["EventShapes"]["S"][29.0 ] = ["/HRS_1985_I201482/d01-x01-y01"]
+analyses["EventShapes"]["S"][14.0 ] = ["/TASSO_1990_S2148048/d06-x01-y01","/TASSO_1984_I195333/d12-x01-y01"]
+analyses["EventShapes"]["S"][22.0 ] = ["/TASSO_1990_S2148048/d06-x01-y02","/TASSO_1984_I195333/d12-x01-y02"]
+analyses["EventShapes"]["S"][29.0 ] = ["/HRS_1985_I201482/d01-x01-y01","/MARKII_1988_I246184/d04-x01-y01",
+ "/MARKII_1988_I246184/d22-x01-y01","/MARKII_1988_I246184/d40-x01-y01"]
analyses["EventShapes"]["S"][30.8 ] = ["/TASSO_1980_I153511/d02-x01-y01"]
+analyses["EventShapes"]["S"][34.0 ] = ["/TASSO_1984_I195333/d12-x01-y03"]
analyses["EventShapes"]["S"][35.0 ] = ["/TASSO_1990_S2148048/d06-x01-y03","/TASSO_1988_I263859/d01-x01-y01"]
analyses["EventShapes"]["S"][44.0 ] = ["/TASSO_1990_S2148048/d06-x01-y04"]
analyses["EventShapes"]["S"][45.0 ] = ["/DELPHI_2003_I620250/d04-x01-y01"]
analyses["EventShapes"]["S"][55.2 ] = ["/AMY_1990_I283337/d16-x01-y01"]
analyses["EventShapes"]["S"][66.0 ] = ["/DELPHI_2003_I620250/d04-x01-y02"]
analyses["EventShapes"]["S"][76.0 ] = ["/DELPHI_2003_I620250/d04-x01-y03"]
analyses["EventShapes"]["S"][91.2 ] = ["/ALEPH_2004_S5765862/d141-x01-y01","/DELPHI_1996_S3430090/d15-x01-y01",
- "/ALEPH_1996_S3486095/d01-x01-y01","/OPAL_2004_S6132243/d10-x01-y01"]
+ "/ALEPH_1996_S3486095/d01-x01-y01","/OPAL_2004_S6132243/d10-x01-y01",
+ "/L3_1992_I334954/d10-x01-y01"]
analyses["EventShapes"]["S"][133.0] = ["/ALEPH_2004_S5765862/d142-x01-y01","/OPAL_2004_S6132243/d10-x01-y02",
"/DELPHI_1999_I499183/d21-x01-y01"]
analyses["EventShapes"]["S"][161.0] = ["/ALEPH_2004_S5765862/d143-x01-y01","/DELPHI_1999_I499183/d21-x01-y02",
"/OPAL_1997_I440721/d07-x01-y01"]
analyses["EventShapes"]["S"][172.0] = ["/ALEPH_2004_S5765862/d144-x01-y01","/DELPHI_1999_I499183/d21-x01-y03",
"/OPAL_2000_I513476/d08-x01-y01"]
analyses["EventShapes"]["S"][177.0] = ["/OPAL_2004_S6132243/d10-x01-y03"]
analyses["EventShapes"]["S"][183.0] = ["/DELPHI_2003_I620250/d66-x01-y01","/ALEPH_2004_S5765862/d145-x01-y01",
"/DELPHI_1999_I499183/d22-x01-y01", "/OPAL_2000_I513476/d08-x01-y02"]
analyses["EventShapes"]["S"][189.0] = ["/DELPHI_2003_I620250/d66-x01-y02","/ALEPH_2004_S5765862/d146-x01-y01",
"/OPAL_2000_I513476/d08-x01-y03"]
analyses["EventShapes"]["S"][192.0] = ["/DELPHI_2003_I620250/d66-x01-y03"]
analyses["EventShapes"]["S"][196.0] = ["/DELPHI_2003_I620250/d66-x01-y04"]
analyses["EventShapes"]["S"][197.0] = ["/OPAL_2004_S6132243/d10-x01-y04"]
analyses["EventShapes"]["S"][200.0] = ["/DELPHI_2003_I620250/d67-x01-y01","/ALEPH_2004_S5765862/d147-x01-y01"]
analyses["EventShapes"]["S"][202.0] = ["/DELPHI_2003_I620250/d67-x01-y02"]
analyses["EventShapes"]["S"][205.0] = ["/DELPHI_2003_I620250/d67-x01-y03"]
analyses["EventShapes"]["S"][206.0] = ["/ALEPH_2004_S5765862/d148-x01-y01"]
analyses["EventShapes"]["S"][207.0] = ["/DELPHI_2003_I620250/d67-x01-y04"]
analyses["EventShapes"]["P"][45.0 ] = ["/DELPHI_2003_I620250/d05-x01-y01"]
analyses["EventShapes"]["P"][66.0 ] = ["/DELPHI_2003_I620250/d05-x01-y02"]
analyses["EventShapes"]["P"][76.0 ] = ["/DELPHI_2003_I620250/d05-x01-y03"]
analyses["EventShapes"]["P"][91.2 ] = ["/DELPHI_1996_S3430090/d17-x01-y01"]
analyses["EventShapes"]["P"][133.0] = ["/ALEPH_2004_S5765862/d126-x01-y01","/DELPHI_1999_I499183/d23-x01-y01"]
analyses["EventShapes"]["P"][161.0] = ["/ALEPH_2004_S5765862/d127-x01-y01","/DELPHI_1999_I499183/d23-x01-y02"]
analyses["EventShapes"]["P"][172.0] = ["/ALEPH_2004_S5765862/d128-x01-y01","/DELPHI_1999_I499183/d23-x01-y03"]
analyses["EventShapes"]["P"][183.0] = ["/DELPHI_2003_I620250/d68-x01-y01","/ALEPH_2004_S5765862/d129-x01-y01",
"/DELPHI_1999_I499183/d24-x01-y01"]
analyses["EventShapes"]["P"][189.0] = ["/DELPHI_2003_I620250/d68-x01-y02","/ALEPH_2004_S5765862/d130-x01-y01"]
analyses["EventShapes"]["P"][192.0] = ["/DELPHI_2003_I620250/d68-x01-y03"]
analyses["EventShapes"]["P"][196.0] = ["/DELPHI_2003_I620250/d68-x01-y04"]
analyses["EventShapes"]["P"][200.0] = ["/DELPHI_2003_I620250/d69-x01-y01","/ALEPH_2004_S5765862/d131-x01-y01"]
analyses["EventShapes"]["P"][202.0] = ["/DELPHI_2003_I620250/d69-x01-y02"]
analyses["EventShapes"]["P"][205.0] = ["/DELPHI_2003_I620250/d69-x01-y03"]
analyses["EventShapes"]["P"][206.0] = ["/ALEPH_2004_S5765862/d132-x01-y01"]
analyses["EventShapes"]["P"][207.0] = ["/DELPHI_2003_I620250/d69-x01-y04"]
analyses["EventShapes"]["A"][12.0 ] = ["/TASSO_1980_I153511/d03-x01-y01"]
analyses["EventShapes"]["A"][14.0 ] = ["/TASSO_1990_S2148048/d07-x01-y01"]
analyses["EventShapes"]["A"][22.0 ] = ["/TASSO_1990_S2148048/d07-x01-y02","/HRS_1985_I201482/d06-x01-y01"]
+analyses["EventShapes"]["A"][29.0 ] = ["/MARKII_1988_I246184/d01-x01-y01","/MARKII_1988_I246184/d19-x01-y01",
+ "/MARKII_1988_I246184/d37-x01-y01"]
analyses["EventShapes"]["A"][30.8 ] = ["/TASSO_1980_I153511/d04-x01-y01"]
analyses["EventShapes"]["A"][35.0 ] = ["/TASSO_1990_S2148048/d07-x01-y03","/TASSO_1988_I263859/d02-x01-y01"]
analyses["EventShapes"]["A"][44.0 ] = ["/TASSO_1990_S2148048/d07-x01-y04"]
analyses["EventShapes"]["A"][55.2 ] = ["/AMY_1990_I283337/d17-x01-y01"]
analyses["EventShapes"]["A"][91.2 ] = ["/ALEPH_2004_S5765862/d118-x01-y01","/DELPHI_1996_S3430090/d16-x01-y01",
- "/ALEPH_1996_S3486095/d02-x01-y01","/OPAL_2004_S6132243/d09-x01-y01"]
+ "/ALEPH_1996_S3486095/d02-x01-y01","/OPAL_2004_S6132243/d09-x01-y01",
+ "/L3_1992_I334954/d11-x01-y01"]
analyses["EventShapes"]["A"][133.0] = ["/ALEPH_2004_S5765862/d119-x01-y01","/OPAL_2004_S6132243/d09-x01-y02",
"/DELPHI_1999_I499183/d25-x01-y01"]
analyses["EventShapes"]["A"][161.0] = ["/ALEPH_2004_S5765862/d120-x01-y01","/DELPHI_1999_I499183/d25-x01-y02",
"/OPAL_1997_I440721/d08-x01-y01"]
analyses["EventShapes"]["A"][172.0] = ["/ALEPH_2004_S5765862/d121-x01-y01","/DELPHI_1999_I499183/d25-x01-y03",
"/OPAL_2000_I513476/d04-x01-y01"]
analyses["EventShapes"]["A"][177.0] = ["/OPAL_2004_S6132243/d09-x01-y03"]
analyses["EventShapes"]["A"][183.0] = ["/DELPHI_2003_I620250/d70-x01-y01","/ALEPH_2004_S5765862/d122-x01-y01",
"/DELPHI_1999_I499183/d26-x01-y01","/OPAL_2000_I513476/d04-x01-y02"]
analyses["EventShapes"]["A"][189.0] = ["/DELPHI_2003_I620250/d70-x01-y02","/ALEPH_2004_S5765862/d123-x01-y01",
"/OPAL_2000_I513476/d04-x01-y03"]
analyses["EventShapes"]["A"][192.0] = ["/DELPHI_2003_I620250/d70-x01-y03"]
analyses["EventShapes"]["A"][196.0] = ["/DELPHI_2003_I620250/d70-x01-y04"]
analyses["EventShapes"]["A"][197.0] = ["/OPAL_2004_S6132243/d09-x01-y04"]
analyses["EventShapes"]["A"][200.0] = ["/DELPHI_2003_I620250/d71-x01-y01","/ALEPH_2004_S5765862/d124-x01-y01"]
analyses["EventShapes"]["A"][202.0] = ["/DELPHI_2003_I620250/d71-x01-y02"]
analyses["EventShapes"]["A"][205.0] = ["/DELPHI_2003_I620250/d71-x01-y03"]
analyses["EventShapes"]["A"][206.0] = ["/ALEPH_2004_S5765862/d125-x01-y01"]
analyses["EventShapes"]["A"][207.0] = ["/DELPHI_2003_I620250/d71-x01-y04"]
# other
+analyses["EventShapes"]["Qx"][29.0 ] = ["/MARKII_1988_I246184/d02-x01-y01","/MARKII_1988_I246184/d20-x01-y01",
+ "/MARKII_1988_I246184/d38-x01-y01"]
analyses["EventShapes"]["Qx" ][55.2] = ["/AMY_1990_I283337/d18-x01-y01"]
+analyses["EventShapes"]["Q21"][29.0] = ["/MARKII_1988_I246184/d03-x01-y01","/MARKII_1988_I246184/d21-x01-y01",
+ "/MARKII_1988_I246184/d39-x01-y01"]
analyses["EventShapes"]["Q21"][55.2] = ["/AMY_1990_I283337/d19-x01-y01"]
analyses["QED"] = ["/ALEPH_1996_S3196992/d03-x01-y01","/ALEPH_1996_S3196992/d04-x01-y01",
"/ALEPH_1996_S3196992/d01-x01-y01","/ALEPH_1996_S3196992/d02-x01-y01",
"/ALEPH_1996_S3196992/d05-x01-y01","/ALEPH_1996_S3196992/d06-x01-y01",
"/ALEPH_1996_S3196992/d07-x01-y01","/ALEPH_1996_S3196992/d08-x01-y01",
"/OPAL_1993_S2692198/d01-x01-y01","/OPAL_1993_S2692198/d02-x01-y01",
"/OPAL_1993_S2692198/d03-x01-y01","/OPAL_1993_S2692198/d03-x01-y02",
"/OPAL_1993_S2692198/d03-x01-y03","/OPAL_1993_S2692198/d03-x01-y04",
"/OPAL_1993_S2692198/d04-x01-y01","/OPAL_1993_S2692198/d04-x01-y02",
"/OPAL_1993_S2692198/d04-x01-y03","/OPAL_1993_S2692198/d04-x01-y04",]
+# W decays
+analyses["WDecays"]["Mult"][0 ] = ["/DELPHI_2001_I526164/d03-x01-y01"]
+analyses["WDecays"]["Mult"][211 ] = ["/DELPHI_2001_I526164/d04-x01-y01","/DELPHI_2001_I526164/d04-x01-y02"]
+analyses["WDecays"]["Mult"][321 ] = ["/DELPHI_2001_I526164/d04-x01-y03","/DELPHI_2001_I526164/d04-x01-y04"]
+analyses["WDecays"]["Mult"][2212] = ["/DELPHI_2001_I526164/d04-x01-y05","/DELPHI_2001_I526164/d04-x01-y06"]
+analyses["WDecays"]["Spectrum"][0 ] = ["/DELPHI_2001_I526164/d05-x01-y01","/DELPHI_2001_I526164/d05-x01-y02",
+ "/DELPHI_2001_I526164/d07-x01-y01","/DELPHI_2001_I526164/d07-x01-y02",
+ "/DELPHI_2001_I526164/d06-x01-y01","/DELPHI_2001_I526164/d08-x01-y01",
+ "/DELPHI_2001_I526164/d09-x01-y01","/DELPHI_2001_I526164/d09-x01-y02",
+ "/DELPHI_2001_I526164/d09-x01-y03","/DELPHI_2001_I526164/d10-x01-y01",
+ "/DELPHI_2001_I526164/d10-x01-y02","/DELPHI_2001_I526164/d10-x01-y03",
+ "/DELPHI_2001_I526164/d13-x01-y01",
+ "/DELPHI_2001_I526164/d14-x01-y01","/DELPHI_2001_I526164/d15-x01-y01",
+ "/DELPHI_2001_I526164/d11-x01-y01","/DELPHI_2001_I526164/d11-x01-y02",
+ "/DELPHI_2001_I526164/d11-x01-y03","/DELPHI_2001_I526164/d12-x01-y01",
+ "/DELPHI_2001_I526164/d12-x01-y02","/DELPHI_2001_I526164/d12-x01-y03"]
+analyses["WDecays"]["Spectrum"][211 ] = ["/DELPHI_2001_I526164/d13-x01-y02","/DELPHI_2001_I526164/d14-x01-y02",
+ "/DELPHI_2001_I526164/d15-x01-y02"]
+analyses["WDecays"]["Spectrum"][321 ] = ["/DELPHI_2001_I526164/d13-x01-y03","/DELPHI_2001_I526164/d14-x01-y03",
+ "/DELPHI_2001_I526164/d15-x01-y03"]
+analyses["WDecays"]["Spectrum"][2212] = ["/DELPHI_2001_I526164/d13-x01-y04","/DELPHI_2001_I526164/d14-x01-y04",
+ "/DELPHI_2001_I526164/d15-x01-y04"]
# tau decays
# 2 body
analyses["TauDecays"]["1pi" ]["MC" ] = ["/MC_TAU_Decay/h_1B_xpi"]
analyses["TauDecays"]["KK" ]["data"] = ["/BABAR_2018_I1679886/d01-x01-y01"]
analyses["TauDecays"]["KK" ]["MC" ] = ["/MC_TAU_Decay/h_2B_m2KK","/MC_TAU_Decay/h_2B_mKK"]
analyses["TauDecays"]["Kpi" ]["data"] = ["/BELLE_2007_I753243/d01-x01-y01"]
analyses["TauDecays"]["Kpi" ]["MC" ] = ["/MC_TAU_Decay/h_2B_m2KpiA","/MC_TAU_Decay/h_2B_m2KpiB",
"/MC_TAU_Decay/h_2B_mKpiA","/MC_TAU_Decay/h_2B_mKpiB"]
analyses["TauDecays"]["2pi" ]["data"] = ["/BELLE_2008_I786560/d01-x01-y01","/ALEPH_2014_I1267648/d01-x01-y01",
"/CLEO_1999_I508944/d01-x01-y01"]
analyses["TauDecays"]["2pi" ]["MC" ] = ["/MC_TAU_Decay/h_2B_m2pipi","/MC_TAU_Decay/h_2B_mpipi"]
analyses["TauDecays"]["3pi" ]["data"] = ["/BELLE_2010_I841618/d01-x01-y01","/BABAR_2007_S7266081/d01-x01-y01",
"/BABAR_2007_S7266081/d02-x01-y01","/BABAR_2007_S7266081/d11-x01-y01",
"/ALEPH_2014_I1267648/d02-x01-y01","/ALEPH_2014_I1267648/d04-x01-y01"]
analyses["TauDecays"]["3pi" ]["MC" ] = ["/MC_TAU_Decay/h_3B_pi0pi0pim_1","/MC_TAU_Decay/h_3B_pi0pi0pim_2","/MC_TAU_Decay/h_3B_pi0pi0pim_3",
"/MC_TAU_Decay/h_3B_pippimpim_1","/MC_TAU_Decay/h_3B_pippimpim_2","/MC_TAU_Decay/h_3B_pippimpim_3"]
analyses["TauDecays"]["Kpipi"]["data"] = ["/BELLE_2010_I841618/d02-x01-y01" ,"/BABAR_2007_S7266081/d03-x01-y01",
"/BABAR_2007_S7266081/d04-x01-y01","/BABAR_2007_S7266081/d05-x01-y01",
"/BABAR_2007_S7266081/d12-x01-y01"]
analyses["TauDecays"]["Kpipi"]["MC" ] = ["/MC_TAU_Decay/h_3B_pi0pi0km_1","/MC_TAU_Decay/h_3B_pi0pi0km_2","/MC_TAU_Decay/h_3B_pi0pi0km_3",
"/MC_TAU_Decay/h_3B_pimk0pi0_1","/MC_TAU_Decay/h_3B_pimk0pi0_2","/MC_TAU_Decay/h_3B_pimk0pi0_3",
"/MC_TAU_Decay/h_3B_pimk0pi0_4"]
analyses["TauDecays"]["KKpi" ]["data"] = ["/BELLE_2010_I841618/d03-x01-y01","/BABAR_2007_S7266081/d06-x01-y01",
"/BABAR_2007_S7266081/d07-x01-y01","/BABAR_2007_S7266081/d08-x01-y01",
"/BABAR_2007_S7266081/d13-x01-y01"]
analyses["TauDecays"]["KKpi" ]["MC" ] = ["/MC_TAU_Decay/h_3B_klpimkl_1","/MC_TAU_Decay/h_3B_klpimkl_2","/MC_TAU_Decay/h_3B_klpimkl_3",
"/MC_TAU_Decay/h_3B_kmpi0k0_1","/MC_TAU_Decay/h_3B_kmpi0k0_2","/MC_TAU_Decay/h_3B_kmpi0k0_3",
"/MC_TAU_Decay/h_3B_kmpi0k0_4","/MC_TAU_Decay/h_3B_kmpimkp_1","/MC_TAU_Decay/h_3B_kmpimkp_2",
"/MC_TAU_Decay/h_3B_kmpimkp_3","/MC_TAU_Decay/h_3B_kmpimkp_4","/MC_TAU_Decay/h_3B_kmpimpip_1",
"/MC_TAU_Decay/h_3B_kmpimpip_2","/MC_TAU_Decay/h_3B_kmpimpip_3","/MC_TAU_Decay/h_3B_kmpimpip_4",
"/MC_TAU_Decay/h_3B_kspimkl_1","/MC_TAU_Decay/h_3B_kspimkl_2","/MC_TAU_Decay/h_3B_kspimkl_3",
"/MC_TAU_Decay/h_3B_kspimkl_4","/MC_TAU_Decay/h_3B_kspimks_1","/MC_TAU_Decay/h_3B_kspimks_2",
"/MC_TAU_Decay/h_3B_kspimks_3"]
analyses["TauDecays"]["3K" ]["data"] = ["/BELLE_2010_I841618/d04-x01-y01","/BABAR_2007_S7266081/d09-x01-y01",
- "/BABAR_2007_S7266081/d10-x01-y01","/BABAR_2007_S7266081/d14-x01-y01"]
+ "/BABAR_2007_S7266081/d10-x01-y01","/BABAR_2007_S7266081/d14-x01-y01",
+ "/BELLE_2006_I725750/d01-x01-y01"]
analyses["TauDecays"]["Keta"]["data"] = ["/CLEOII_1996_I415409/d01-x01-y01"]
analyses["TauDecays"]["Keta"]["MC" ] = ["/MC_TAU_Decay/h_2B_m2Keta","/MC_TAU_Decay/h_2B_mKeta"]
analyses["TauDecays"]["lnu" ]["MC" ] = ["/MC_TAU_Decay/h_2B_m2enu","/MC_TAU_Decay/h_2B_m2munu",
"/MC_TAU_Decay/h_2B_menu","/MC_TAU_Decay/h_2B_mmunu"]
analyses["TauDecays"]["2pieta"]["MC" ] = ["/MC_TAU_Decay/h_3B_pimpi0eta_1","/MC_TAU_Decay/h_3B_pimpi0eta_2",
"/MC_TAU_Decay/h_3B_pimpi0eta_3","/MC_TAU_Decay/h_3B_pimpi0eta_4"]
analyses["TauDecays"]["2pigamma"]["MC" ] = ["/MC_TAU_Decay/h_3B_pimpi0gamma_1","/MC_TAU_Decay/h_3B_pimpi0gamma_2",
"/MC_TAU_Decay/h_3B_pimpi0gamma_3","/MC_TAU_Decay/h_3B_pimpi0gamma_4"]
analyses["TauDecays"]["4pi"]["data"] = ["/ALEPH_2014_I1267648/d03-x01-y01","/ALEPH_2014_I1267648/d05-x01-y01",
"/ALEPH_1996_I421984/d01-x01-y01","/ALEPH_1996_I421984/d02-x01-y01",
"/ALEPH_1996_I421984/d03-x01-y01","/ALEPH_1996_I421984/d06-x01-y01"]
analyses["TauDecays"]["4pi"]["MC" ] = ["/MC_TAU_Decay/h_4B_pipi_1","/MC_TAU_Decay/h_4B_pipi_2",
"/MC_TAU_Decay/h_4B_pipi_3","/MC_TAU_Decay/h_4B_pipi_4",
"/MC_TAU_Decay/h_4B_pipi_5","/MC_TAU_Decay/h_4B_pipi_6",
"/MC_TAU_Decay/h_4B_pipipi_1","/MC_TAU_Decay/h_4B_pipipi_2",
"/MC_TAU_Decay/h_4B_pipipi_3","/MC_TAU_Decay/h_4B_pipipi_4",
"/MC_TAU_Decay/h_4B_pipipi_5","/MC_TAU_Decay/h_4B_pipipipi_1",
"/MC_TAU_Decay/h_4B_pipipipi_2"]
analyses["TauDecays"]["5pi"]["MC" ] = ["/MC_TAU_Decay/h_5B_pipi1_1","/MC_TAU_Decay/h_5B_pipi1_2",
"/MC_TAU_Decay/h_5B_pipi1_3","/MC_TAU_Decay/h_5B_pipi1_4",
"/MC_TAU_Decay/h_5B_pipi1_5","/MC_TAU_Decay/h_5B_pipi2_1",
"/MC_TAU_Decay/h_5B_pipi2_2","/MC_TAU_Decay/h_5B_pipi3_1",
"/MC_TAU_Decay/h_5B_pipi3_2","/MC_TAU_Decay/h_5B_pipi3_3",
"/MC_TAU_Decay/h_5B_pipipi1_1","/MC_TAU_Decay/h_5B_pipipi1_2",
"/MC_TAU_Decay/h_5B_pipipi1_3","/MC_TAU_Decay/h_5B_pipipi1_4",
"/MC_TAU_Decay/h_5B_pipipi1_5","/MC_TAU_Decay/h_5B_pipipi2_1",
"/MC_TAU_Decay/h_5B_pipipi2_2","/MC_TAU_Decay/h_5B_pipipi3_1",
"/MC_TAU_Decay/h_5B_pipipi3_2","/MC_TAU_Decay/h_5B_pipipi3_3",
"/MC_TAU_Decay/h_5B_pipipipi1_1","/MC_TAU_Decay/h_5B_pipipipi1_2",
"/MC_TAU_Decay/h_5B_pipipipi1_3","/MC_TAU_Decay/h_5B_pipipipi2_1",
"/MC_TAU_Decay/h_5B_pipipipi2_2","/MC_TAU_Decay/h_5B_pipipipi3_1",
"/MC_TAU_Decay/h_5B_pipipipi3_2","/MC_TAU_Decay/h_5B_q1",
"/MC_TAU_Decay/h_5B_q2","/MC_TAU_Decay/h_5B_q3"]
analyses["TauDecays"]["6pi"]["data"] = ["/CLEOII_1994_I373188/d01-x01-y01"]
+analyses["EventShapes"]["2jet_cam"][200.2 ] = ["/L3_2004_I652683/d19-x01-y01"]
+analyses["EventShapes"]["3jet_cam"][200.2 ] = ["/L3_2004_I652683/d19-x01-y02"]
+analyses["EventShapes"]["4jet_cam"][200.2 ] = ["/L3_2004_I652683/d19-x01-y03"]
+analyses["EventShapes"]["5jet_cam"][200.2 ] = ["/L3_2004_I652683/d19-x01-y04"]
+analyses["EventShapes"]["2jet_cam"][206.2 ] = ["/L3_2004_I652683/d20-x01-y01"]
+analyses["EventShapes"]["3jet_cam"][206.2 ] = ["/L3_2004_I652683/d20-x01-y02"]
+analyses["EventShapes"]["4jet_cam"][206.2 ] = ["/L3_2004_I652683/d20-x01-y03"]
+analyses["EventShapes"]["5jet_cam"][206.2 ] = ["/L3_2004_I652683/d20-x01-y04"]
+# jade jet rates
analyses["EventShapes"]["2jet_jade"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d07-x01-y01"]
analyses["EventShapes"]["3jet_jade"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d07-x01-y02"]
analyses["EventShapes"]["4jet_jade"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d07-x01-y03"]
analyses["EventShapes"]["5jet_jade"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d07-x01-y04"]
analyses["EventShapes"]["6jet_jade"][35.0 ] = ["/JADE_OPAL_2000_S4300807/d07-x01-y05"]
analyses["EventShapes"]["2jet_jade"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d08-x01-y01"]
analyses["EventShapes"]["3jet_jade"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d08-x01-y02"]
analyses["EventShapes"]["4jet_jade"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d08-x01-y03"]
analyses["EventShapes"]["5jet_jade"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d08-x01-y04"]
analyses["EventShapes"]["6jet_jade"][44.0 ] = ["/JADE_OPAL_2000_S4300807/d08-x01-y05"]
-analyses["EventShapes"]["2jet_jade"][91.2 ] = ["/JADE_OPAL_2000_S4300807/d09-x01-y01"]
-analyses["EventShapes"]["3jet_jade"][91.2 ] = ["/JADE_OPAL_2000_S4300807/d09-x01-y02"]
-analyses["EventShapes"]["4jet_jade"][91.2 ] = ["/JADE_OPAL_2000_S4300807/d09-x01-y03"]
-analyses["EventShapes"]["5jet_jade"][91.2 ] = ["/JADE_OPAL_2000_S4300807/d09-x01-y04"]
+analyses["EventShapes"]["2jet_jade"][91.2 ] = ["/JADE_OPAL_2000_S4300807/d09-x01-y01","/L3_1990_I298078/d01-x01-y01",
+ "/DELPHI_1990_I297698/d01-x01-y01"]
+analyses["EventShapes"]["3jet_jade"][91.2 ] = ["/JADE_OPAL_2000_S4300807/d09-x01-y02","/L3_1990_I298078/d01-x01-y02",
+ "/DELPHI_1990_I297698/d01-x01-y02"]
+analyses["EventShapes"]["4jet_jade"][91.2 ] = ["/JADE_OPAL_2000_S4300807/d09-x01-y03","/L3_1990_I298078/d01-x01-y03",
+ "/DELPHI_1990_I297698/d01-x01-y03"]
+analyses["EventShapes"]["5jet_jade"][91.2 ] = ["/JADE_OPAL_2000_S4300807/d09-x01-y04","/DELPHI_1990_I297698/d01-x01-y04"]
analyses["EventShapes"]["6jet_jade"][91.2 ] = ["/JADE_OPAL_2000_S4300807/d09-x01-y05"]
+analyses["EventShapes"]["2jet_jade"][130.1] = ["/L3_2004_I652683/d01-x01-y01"]
+analyses["EventShapes"]["3jet_jade"][130.1] = ["/L3_2004_I652683/d01-x01-y02"]
+analyses["EventShapes"]["4jet_jade"][130.1] = ["/L3_2004_I652683/d01-x01-y03"]
+analyses["EventShapes"]["5jet_jade"][130.1] = ["/L3_2004_I652683/d01-x01-y04"]
analyses["EventShapes"]["2jet_jade"][133.0] = ["/JADE_OPAL_2000_S4300807/d10-x01-y01"]
analyses["EventShapes"]["3jet_jade"][133.0] = ["/JADE_OPAL_2000_S4300807/d10-x01-y02"]
analyses["EventShapes"]["4jet_jade"][133.0] = ["/JADE_OPAL_2000_S4300807/d10-x01-y03"]
analyses["EventShapes"]["5jet_jade"][133.0] = ["/JADE_OPAL_2000_S4300807/d10-x01-y04"]
analyses["EventShapes"]["6jet_jade"][133.0] = ["/JADE_OPAL_2000_S4300807/d10-x01-y05"]
+analyses["EventShapes"]["2jet_jade"][136.1] = ["/L3_2004_I652683/d02-x01-y01"]
+analyses["EventShapes"]["3jet_jade"][136.1] = ["/L3_2004_I652683/d02-x01-y02"]
+analyses["EventShapes"]["4jet_jade"][136.1] = ["/L3_2004_I652683/d02-x01-y03"]
+analyses["EventShapes"]["5jet_jade"][136.1] = ["/L3_2004_I652683/d02-x01-y04"]
analyses["EventShapes"]["2jet_jade"][161.0] = ["/JADE_OPAL_2000_S4300807/d11-x01-y01"]
analyses["EventShapes"]["3jet_jade"][161.0] = ["/JADE_OPAL_2000_S4300807/d11-x01-y02"]
analyses["EventShapes"]["4jet_jade"][161.0] = ["/JADE_OPAL_2000_S4300807/d11-x01-y03"]
analyses["EventShapes"]["5jet_jade"][161.0] = ["/JADE_OPAL_2000_S4300807/d11-x01-y04"]
analyses["EventShapes"]["6jet_jade"][161.0] = ["/JADE_OPAL_2000_S4300807/d11-x01-y05"]
+analyses["EventShapes"]["2jet_jade"][161.3] = ["/L3_2004_I652683/d03-x01-y01"]
+analyses["EventShapes"]["3jet_jade"][161.3] = ["/L3_2004_I652683/d03-x01-y02"]
+analyses["EventShapes"]["4jet_jade"][161.3] = ["/L3_2004_I652683/d03-x01-y03"]
+analyses["EventShapes"]["5jet_jade"][161.3] = ["/L3_2004_I652683/d03-x01-y04"]
analyses["EventShapes"]["2jet_jade"][172.0] = ["/JADE_OPAL_2000_S4300807/d12-x01-y01"]
analyses["EventShapes"]["3jet_jade"][172.0] = ["/JADE_OPAL_2000_S4300807/d12-x01-y02"]
analyses["EventShapes"]["4jet_jade"][172.0] = ["/JADE_OPAL_2000_S4300807/d12-x01-y03"]
analyses["EventShapes"]["5jet_jade"][172.0] = ["/JADE_OPAL_2000_S4300807/d12-x01-y04"]
analyses["EventShapes"]["6jet_jade"][172.0] = ["/JADE_OPAL_2000_S4300807/d12-x01-y05"]
+analyses["EventShapes"]["2jet_jade"][172.3] = ["/L3_2004_I652683/d04-x01-y01"]
+analyses["EventShapes"]["3jet_jade"][172.3] = ["/L3_2004_I652683/d04-x01-y02"]
+analyses["EventShapes"]["4jet_jade"][172.3] = ["/L3_2004_I652683/d04-x01-y03"]
+analyses["EventShapes"]["5jet_jade"][172.3] = ["/L3_2004_I652683/d04-x01-y04"]
+analyses["EventShapes"]["2jet_jade"][182.8] = ["/L3_2004_I652683/d05-x01-y01"]
+analyses["EventShapes"]["3jet_jade"][182.8] = ["/L3_2004_I652683/d05-x01-y02"]
+analyses["EventShapes"]["4jet_jade"][182.8] = ["/L3_2004_I652683/d05-x01-y03"]
+analyses["EventShapes"]["5jet_jade"][182.8] = ["/L3_2004_I652683/d05-x01-y04"]
analyses["EventShapes"]["2jet_jade"][183.0] = ["/JADE_OPAL_2000_S4300807/d13-x01-y01"]
analyses["EventShapes"]["3jet_jade"][183.0] = ["/JADE_OPAL_2000_S4300807/d13-x01-y02"]
analyses["EventShapes"]["4jet_jade"][183.0] = ["/JADE_OPAL_2000_S4300807/d13-x01-y03"]
analyses["EventShapes"]["5jet_jade"][183.0] = ["/JADE_OPAL_2000_S4300807/d13-x01-y04"]
analyses["EventShapes"]["6jet_jade"][183.0] = ["/JADE_OPAL_2000_S4300807/d13-x01-y05"]
+analyses["EventShapes"]["2jet_jade"][188.6] = ["/L3_2004_I652683/d06-x01-y01"]
+analyses["EventShapes"]["3jet_jade"][188.6] = ["/L3_2004_I652683/d06-x01-y02"]
+analyses["EventShapes"]["4jet_jade"][188.6] = ["/L3_2004_I652683/d06-x01-y03"]
+analyses["EventShapes"]["5jet_jade"][188.6] = ["/L3_2004_I652683/d06-x01-y04"]
analyses["EventShapes"]["2jet_jade"][189.0] = ["/JADE_OPAL_2000_S4300807/d14-x01-y01"]
analyses["EventShapes"]["3jet_jade"][189.0] = ["/JADE_OPAL_2000_S4300807/d14-x01-y02"]
analyses["EventShapes"]["4jet_jade"][189.0] = ["/JADE_OPAL_2000_S4300807/d14-x01-y03"]
analyses["EventShapes"]["5jet_jade"][189.0] = ["/JADE_OPAL_2000_S4300807/d14-x01-y04"]
analyses["EventShapes"]["6jet_jade"][189.0] = ["/JADE_OPAL_2000_S4300807/d14-x01-y05"]
+analyses["EventShapes"]["2jet_jade"][194.4] = ["/L3_2004_I652683/d07-x01-y01"]
+analyses["EventShapes"]["3jet_jade"][194.4] = ["/L3_2004_I652683/d07-x01-y02"]
+analyses["EventShapes"]["4jet_jade"][194.4] = ["/L3_2004_I652683/d07-x01-y03"]
+analyses["EventShapes"]["5jet_jade"][194.4] = ["/L3_2004_I652683/d07-x01-y04"]
+analyses["EventShapes"]["2jet_jade"][202.2] = ["/L3_2004_I652683/d08-x01-y01"]
+analyses["EventShapes"]["3jet_jade"][202.2] = ["/L3_2004_I652683/d08-x01-y02"]
+analyses["EventShapes"]["4jet_jade"][202.2] = ["/L3_2004_I652683/d08-x01-y03"]
+analyses["EventShapes"]["5jet_jade"][202.2] = ["/L3_2004_I652683/d08-x01-y04"]
+analyses["EventShapes"]["2jet_jade"][206.2] = ["/L3_2004_I652683/d09-x01-y01"]
+analyses["EventShapes"]["3jet_jade"][206.2] = ["/L3_2004_I652683/d09-x01-y02"]
+analyses["EventShapes"]["4jet_jade"][206.2] = ["/L3_2004_I652683/d09-x01-y03"]
+analyses["EventShapes"]["5jet_jade"][206.2] = ["/L3_2004_I652683/d09-x01-y04"]
# polarization
# rho +/-
analyses["Polarization"][213]["rho00"][91.2] = ["/OPAL_2000_I502750/d01-x01-y01"]
analyses["Polarization"][213]["cos" ][91.2] = ["/OPAL_2000_I502750/ctheta_rho_0","/OPAL_2000_I502750/ctheta_rho_1",
"/OPAL_2000_I502750/ctheta_rho_2","/OPAL_2000_I502750/ctheta_rho_3",
"/OPAL_2000_I502750/ctheta_rho_4","/OPAL_2000_I502750/ctheta_rho_all"]
# omega
analyses["Polarization"][223]["rho00"][91.2] = ["/OPAL_2000_I502750/d02-x01-y01","/OPAL_2000_I502750/d02-x02-y01"]
analyses["Polarization"][223]["cos" ][91.2] = ["/OPAL_2000_I502750/ctheta_omega_0","/OPAL_2000_I502750/ctheta_omega_1",
"/OPAL_2000_I502750/ctheta_omega_2","/OPAL_2000_I502750/ctheta_omega_3",
"/OPAL_2000_I502750/ctheta_omega_4","/OPAL_2000_I502750/ctheta_omega_all"]
# phi
analyses["Polarization"][333]["rho00"][91.2] = ["/OPAL_1997_I440103/d01-x01-y01"]
analyses["Polarization"][333]["rho10"][91.2] = ["/OPAL_1997_I440103/d01-x01-y02","/OPAL_1997_I440103/d01-x01-y04","/OPAL_1997_I440103/d01-x01-y05"]
analyses["Polarization"][333]["rho11"][91.2] = ["/OPAL_1997_I440103/d01-x01-y03"]
analyses["Polarization"][333]["cos" ][91.2] = ["/OPAL_1997_I440103/d05-x01-y01"]
analyses["Polarization"][333]["phi" ][91.2] = ["/OPAL_1997_I440103/d05-x01-y02","/OPAL_1997_I440103/d05-x01-y03"]
# K*0
analyses["Polarization"][313]["rho00"][91.2] = ["/OPAL_1997_S3608263/d02-x01-y01"]
analyses["Polarization"][313]["rho10"][91.2] = ["/OPAL_1997_S3608263/d02-x01-y01"]
analyses["Polarization"][313]["rho11"][91.2] = ["/OPAL_1997_S3608263/d02-x01-y02","/OPAL_1997_S3608263/d03-x01-y01",
"/OPAL_1997_S3608263/d03-x02-y01","/OPAL_1997_S3608263/d04-x01-y01",
"/OPAL_1997_S3608263/d04-x01-y02","/OPAL_1997_S3608263/d04-x02-y01",
"/OPAL_1997_S3608263/d04-x02-y02"]
analyses["Polarization"][313]["cos"][91.2] = ["/OPAL_1997_S3608263/ctheta_00","/OPAL_1997_S3608263/ctheta_01",
"/OPAL_1997_S3608263/ctheta_02","/OPAL_1997_S3608263/ctheta_03",
"/OPAL_1997_S3608263/ctheta_04","/OPAL_1997_S3608263/ctheta_05",
"/OPAL_1997_S3608263/ctheta_06","/OPAL_1997_S3608263/ctheta_07",
"/OPAL_1997_S3608263/ctheta_08","/OPAL_1997_S3608263/ctheta_09",
"/OPAL_1997_S3608263/ctheta_10","/OPAL_1997_S3608263/ctheta_11",
"/OPAL_1997_S3608263/ctheta_large"]
analyses["Polarization"][313]["phi"][91.2] = ["/OPAL_1997_S3608263/alpha_00","/OPAL_1997_S3608263/alpha_01",
"/OPAL_1997_S3608263/alpha_02","/OPAL_1997_S3608263/alpha_03",
"/OPAL_1997_S3608263/alpha_04","/OPAL_1997_S3608263/alpha_05",
"/OPAL_1997_S3608263/alpha_06","/OPAL_1997_S3608263/alpha_07",
"/OPAL_1997_S3608263/alpha_08","/OPAL_1997_S3608263/alpha_09",
"/OPAL_1997_S3608263/alpha_10","/OPAL_1997_S3608263/alpha_11",
"/OPAL_1997_S3608263/alpha_high_00","/OPAL_1997_S3608263/alpha_high_01",
"/OPAL_1997_S3608263/alpha_high_02","/OPAL_1997_S3608263/alpha_high_03",
"/OPAL_1997_S3608263/alpha_low_00","/OPAL_1997_S3608263/alpha_low_01",
"/OPAL_1997_S3608263/alpha_low_02","/OPAL_1997_S3608263/alpha_low_03",]
# D*
analyses["Polarization"][413]["rho00"][10.5] = ["/CLEO_1991_I314060/d01-x01-y02","/CLEO_1998_I467595/d04-x01-y01"]
analyses["Polarization"][413]["alpha"][10.5] = ["/CLEO_1991_I314060/d01-x01-y01","/CLEO_1991_I314060/d01-x01-y03",
"/CLEO_1998_I467595/d03-x01-y01"]
analyses["Polarization"][413]["cos" ][10.5] = ["/CLEO_1991_I314060/d02-x01-y01","/CLEO_1991_I314060/d02-x01-y02",
"/CLEO_1991_I314060/d02-x01-y03","/CLEO_1991_I314060/d02-x01-y04",
"/CLEO_1991_I314060/d02-x01-y05","/CLEO_1991_I314060/d02-x01-y06",
"/CLEO_1998_I467595/d05-x01-y01","/CLEO_1998_I467595/d05-x01-y02",
"/CLEO_1998_I467595/d05-x01-y03","/CLEO_1998_I467595/d05-x01-y04",
"/CLEO_1998_I467595/d05-x01-y05","/CLEO_1998_I467595/d05-x01-y06"]
analyses["Polarization"][413]["rho00"][29.0] = ["/TPC_1991_I316132/d02-x01-y01","/TPC_1991_I316132/d02-x02-y01",
"/HRS_1987_I250823/d01-x01-y01","/HRS_1987_I250823/d01-x02-y01",
"/HRS_1987_I250823/d01-x03-y01","/HRS_1987_I250823/d02-x01-y01",
"/HRS_1987_I250823/d03-x01-y01","/HRS_1987_I250823/d03-x02-y01",
"/HRS_1987_I250823/d04-x01-y01","/HRS_1987_I250823/d05-x01-y01",
"/HRS_1987_I250823/d06-x01-y01"]
analyses["Polarization"][413]["rho10"][29.0] = ["/TPC_1991_I316132/d02-x01-y03","/TPC_1991_I316132/d02-x02-y03",
"/HRS_1987_I250823/d01-x01-y03","/HRS_1987_I250823/d01-x02-y03",
"/HRS_1987_I250823/d01-x03-y03","/HRS_1987_I250823/d02-x01-y03",
"/HRS_1987_I250823/d03-x01-y03","/HRS_1987_I250823/d03-x02-y03",
"/HRS_1987_I250823/d04-x01-y03","/HRS_1987_I250823/d05-x01-y03",
"/HRS_1987_I250823/d06-x01-y03"]
analyses["Polarization"][413]["rho11"][29.0] = ["/TPC_1991_I316132/d02-x01-y02","/TPC_1991_I316132/d02-x02-y02",
"/HRS_1987_I250823/d01-x01-y02","/HRS_1987_I250823/d01-x02-y02",
"/HRS_1987_I250823/d01-x03-y02","/HRS_1987_I250823/d02-x01-y02",
"/HRS_1987_I250823/d03-x01-y02","/HRS_1987_I250823/d03-x02-y02",
"/HRS_1987_I250823/d04-x01-y02","/HRS_1987_I250823/d05-x01-y02",
"/HRS_1987_I250823/d06-x01-y02"]
analyses["Polarization"][413]["alpha"][29.0] = ["/TPC_1991_I316132/d01-x01-y01","/TPC_1991_I316132/d01-x02-y01"]
analyses["Polarization"][413]["cos"][29.0] = ["/TPC_1991_I316132/ctheta_0","/TPC_1991_I316132/ctheta_1",
"/TPC_1991_I316132/ctheta_2","/TPC_1991_I316132/ctheta_3",
"/TPC_1991_I316132/ctheta_4","/TPC_1991_I316132/ctheta_5",
"/TPC_1991_I316132/ctheta_all",]
analyses["Polarization"][413]["phi"][29.0] = ["/TPC_1991_I316132/h_01_0","/TPC_1991_I316132/h_01_1",
"/TPC_1991_I316132/h_01_2","/TPC_1991_I316132/h_01_3",
"/TPC_1991_I316132/h_01_4","/TPC_1991_I316132/h_01_5",
"/TPC_1991_I316132/h_01_all","/TPC_1991_I316132/phi_0",
"/TPC_1991_I316132/phi_1","/TPC_1991_I316132/phi_2",
"/TPC_1991_I316132/phi_3","/TPC_1991_I316132/phi_4",
"/TPC_1991_I316132/phi_5","/TPC_1991_I316132/phi_all"]
analyses["Polarization"][413]["rho00"][91.2] = ["/OPAL_1997_I440103/d03-x01-y01"]
analyses["Polarization"][413]["rho11"][91.2] = ["/OPAL_1997_I440103/d03-x01-y02"]
analyses["Polarization"][413]["cos" ][91.2] = ["/OPAL_1997_I440103/d06-x01-y01"]
analyses["Polarization"][413]["phi" ][91.2] = ["/OPAL_1997_I440103/d07-x01-y01"]
# B*
analyses["Polarization"][513]["rho00"][91.2] = ["/ALEPH_1995_I398426/d02-x01-y01","/DELPHI_1995_I395026/d03-x01-y01",
"/OPAL_1996_I428493/d02-x01-y01","/OPAL_1997_I440103/d04-x01-y01"]
analyses["Polarization"][513]["cos" ][91.2] = ["/DELPHI_1995_I395026/d05-x01-y01","/OPAL_1996_I428493/d03-x01-y01",
"/OPAL_1997_I440103/d08-x01-y01","/ALEPH_1995_I398426/d03-x01-y01"]
# Lambda0
analyses["Polarization"][3122]["rho11"][10.58] = ["/BELLE_2019_I1687566/d01-x01-y01","/BELLE_2019_I1687566/d01-x01-y02",
"/BELLE_2019_I1687566/d01-x02-y01","/BELLE_2019_I1687566/d01-x02-y02",
"/BELLE_2019_I1687566/d01-x03-y01","/BELLE_2019_I1687566/d01-x03-y02",
"/BELLE_2019_I1687566/d01-x04-y01","/BELLE_2019_I1687566/d01-x04-y02",
"/BELLE_2019_I1687566/d02-x01-y01","/BELLE_2019_I1687566/d02-x01-y02",
"/BELLE_2019_I1687566/d02-x01-y03","/BELLE_2019_I1687566/d02-x01-y04",
"/BELLE_2019_I1687566/d02-x01-y05","/BELLE_2019_I1687566/d02-x01-y06",
"/BELLE_2019_I1687566/d02-x01-y07","/BELLE_2019_I1687566/d02-x01-y08",
"/BELLE_2019_I1687566/d02-x02-y01","/BELLE_2019_I1687566/d02-x02-y02",
"/BELLE_2019_I1687566/d02-x02-y03","/BELLE_2019_I1687566/d02-x02-y04",
"/BELLE_2019_I1687566/d02-x02-y05","/BELLE_2019_I1687566/d02-x02-y06",
"/BELLE_2019_I1687566/d02-x02-y07","/BELLE_2019_I1687566/d02-x02-y08",
"/BELLE_2019_I1687566/d02-x03-y01","/BELLE_2019_I1687566/d02-x03-y02",
"/BELLE_2019_I1687566/d02-x03-y03","/BELLE_2019_I1687566/d02-x03-y04",
"/BELLE_2019_I1687566/d02-x03-y05","/BELLE_2019_I1687566/d02-x03-y06",
"/BELLE_2019_I1687566/d02-x03-y07","/BELLE_2019_I1687566/d02-x03-y08",
"/BELLE_2019_I1687566/d02-x04-y01","/BELLE_2019_I1687566/d02-x04-y02",
"/BELLE_2019_I1687566/d02-x04-y03","/BELLE_2019_I1687566/d02-x04-y04",
"/BELLE_2019_I1687566/d02-x04-y05","/BELLE_2019_I1687566/d02-x04-y06",
"/BELLE_2019_I1687566/d02-x04-y07","/BELLE_2019_I1687566/d02-x04-y08",
"/BELLE_2019_I1687566/d03-x01-y01","/BELLE_2019_I1687566/d03-x01-y02",
"/BELLE_2019_I1687566/d03-x01-y03","/BELLE_2019_I1687566/d03-x01-y04",
"/BELLE_2019_I1687566/d03-x01-y05","/BELLE_2019_I1687566/d03-x01-y06",]
analyses["Polarization"][3122]["rho00"][91.2] = ["/OPAL_1997_I447188/d01-x01-y01","/OPAL_1997_I447188/d01-x01-y02",
"/ALEPH_1996_I415745/d01-x01-y01","/ALEPH_1996_I415745/d01-x02-y01"]
analyses["Polarization"][3122]["rho11"][91.2] = ["/OPAL_1997_I447188/d02-x01-y01","/OPAL_1997_I447188/d02-x01-y02",
"/OPAL_1997_I447188/d02-x01-y03","/OPAL_1997_I447188/d02-x01-y04",
"/ALEPH_1996_I415745/d02-x01-y01","/ALEPH_1996_I415745/d02-x02-y01",
"/ALEPH_1996_I415745/d02-x03-y01","/ALEPH_1996_I415745/d02-x04-y01"]
analyses["Polarization"][3122]["cos" ][91.2] = ["/OPAL_1997_I447188/d04-x01-y01","/OPAL_1997_I447188/d04-x01-y02",
"/OPAL_1997_I447188/d04-x01-y03","/OPAL_1997_I447188/d04-x01-y04"]
analyses["Polarization"][3122]["phi" ][91.2] = ["/OPAL_1997_I447188/d05-x01-y01","/OPAL_1997_I447188/d05-x01-y02",
"/OPAL_1997_I447188/d05-x01-y03","/OPAL_1997_I447188/d05-x01-y04"]
# bottom baryons
analyses["Polarization"][5122]["rho00"][91.2] = ["/OPAL_1998_I474012/d01-x01-y01","/DELPHI_2000_I513614/d01-x01-y01",
"/ALEPH_1996_I402895/d01-x01-y01"]
analyses["Polarization"][5122]["Other"][91.2] = ["/DELPHI_2000_I513614/El","/DELPHI_2000_I513614/Ev",
"/OPAL_1998_I474012/El","/OPAL_1998_I474012/Ev",
"/OPAL_1998_I474012/ratio","/ALEPH_1996_I402895/El",
"/ALEPH_1996_I402895/Ev"]
# find all the figures
figures=glob.glob("%s/*/*.dat" % directory)
used=[]
plotOutput="""<div style="float:left; font-size:smaller; font-weight:bold;">
<a href="#{name}">&#9875;</a><a href="{dat}">&#8984</a> {name}: {energy} GeV<br/>
<a name="{name}"><a href="{pdf}">
<img src="{png}">
</a></a>
</div>"""
plotOutput2="""<div style="float:left; font-size:smaller; font-weight:bold;">
<a href="#{name}">&#9875;</a><a href="{dat}">&#8984</a> {name}<br/>
<a name="{name}"><a href="{pdf}">
<img src="{png}">
</a></a>
</div>"""
def writePlots(plots,output) :
global figures
output.write("<div style=\"float:none; overflow:auto; width:100%\">\n")
for energy in sorted(plots.keys()) :
try :
float(energy)
except:
continue
for name in sorted(plots[energy]) :
dat=name[1:] +".dat"
figName = ("%s/%s" %(directory,dat))
if(figName not in figures) :
continue
used.append(figName)
pdf=name[1:] +".pdf"
png=name[1:] +".png"
output.write(plotOutput.format(name=name[1:],pdf=pdf,png=png,dat=dat,energy=energy))
output.write("\n")
output.write("</div>")
def writePlots2(plots,output) :
global figures
output.write("<div style=\"float:none; overflow:auto; width:100%\">\n")
for name in sorted(plots) :
dat=name[1:] +".dat"
figName = ("%s/%s" %(directory,dat))
tempName=figName.replace(".dat","")
found = False
names=[]
for name in figures :
if(tempName+"_" in name or tempName+".dat"==name) :
found=True
names.append(name)
if(not found) : continue
for name in names :
used.append(name)
trim = name[:-4].replace("%s/"%directory,"")
pdf=trim+".pdf"
png=trim+".png"
dat=trim+".dat"
output.write(plotOutput2.format(name=trim,pdf=pdf,png=png,dat=dat))
output.write("\n")
output.write("</div>")
def writeMisc(index) :
global figures,used
for val in used :
if(val in figures) :
del figures[figures.index(val)]
index.write("<li> <a href=\"misc.html\">Other Plots</a>\n")
print ('Unused figures',len(figures))
for val in figures:
print (val)
misc=open(os.path.join(directory,"misc.html"),'w')
misc.write(header.format(title="Comparisions of Herwig7 and Miscellaneous $e^+e^-$ Data"))
misc.write("<div style=\"float:none; overflow:auto; width:100%\">\n")
for val in sorted(figures) :
name=val.replace(directory,"").replace(".dat","")
dat=name[1:] +".dat"
figName = ("%s/%s" %(directory,dat))
if(figName not in figures) : continue
del figures[figures.index(figName)]
pdf=name[1:] +".pdf"
png=name[1:] +".png"
misc.write(plotOutput.format(name=name[1:],pdf=pdf,png=png,dat=dat,energy=""))
misc.write("\n")
misc.write("</div>")
# footer
misc.write("</body>\n</html>")
misc.close()
def writeQED(index) :
index.write("<li> <a href=\"qed.html\">QED Radiation</a>\n")
qed=open(os.path.join(directory,"qed.html"),'w')
qed.write(header.format(title="Comparisions of Herwig7 and Photon Radiation Data"))
writePlots2(analyses["QED"],qed)
# footer
qed.write("</body>\n</html>")
qed.close()
+def writeWDecays(index) :
+ index.write("<li> <a href=\"W.html\">W Decays</a>\n")
+ decays=open(os.path.join(directory,"W.html"),'w')
+ decays.write(header.format(title="Comparisions of Herwig7 and W Decay Data"))
+ index.write("<ul>\n")
+ # multiplicities
+ decays.write("<h3 id=\"mult\">Multiplicities</h3>\n")
+ index.write("<li> <a href=\"W.html#mult\">Multiplicities:</a>")
+ if(len(analyses["WDecays"]["Mult"]) !=0) :
+ for prod,plots in sorted(analyses["WDecays"]["Mult"].items()):
+ if(len(plots)==0) : continue
+ if(prod!=0) :
+ decays.write("<h5>Multiplicity of %s</h5>\n" % particleNames[prod])
+ else :
+ decays.write("<h5>Multiplicity of Charged Particles</h5>\n")
+ writePlots2(plots,decays)
+
+ decays.write("<h3 id=\"spect\">Spectra</h3>\n")
+ index.write("<li> <a href=\"W.html#spect\">Spectra:</a>")
+ # spectra
+ if(len(analyses["WDecays"]["Spectrum"]) !=0) :
+ for prod,plots in sorted(analyses["WDecays"]["Spectrum"].items()):
+ if(len(plots)==0) : continue
+ if(prod!=0) :
+ decays.write("<h5>Spectrum of %s</h5>\n" % particleNames[prod])
+ else :
+ decays.write("<h5>Spectrum of Charged Particles</h5>\n")
+ writePlots2(plots,decays)
+
+ # footer
+ index.write("</ul>\n")
+ decays.write("</body>\n</html>")
+ decays.close()
+
+
+
def writeTauDecays(index) :
index.write("<li> <a href=\"taus.html\">Tau Decays</a>\n")
decays=open(os.path.join(directory,"taus.html"),'w')
decays.write(header.format(title="Comparisions of Herwig7 and Tau Decay Data"))
names = { "1pi" : "$\\tau\\to\\nu_\\tau\\pi^-$",
"2pi" : "$\\tau\\to\\nu_\\tau\\pi^-\\pi^0$",
"Kpi" : "$\\tau\\to\\nu_\\tau K\\pi$",
"KK" : "$\\tau\\to\\nu_\\tau KK$",
"lnu" : "$\\tau\\to\\nu_\\tau \\ell\\nu$",
"Keta" : "$\\tau\\to\\nu_\\tau K\\eta$",
"3pi" : "$\\tau\\to\\nu_\\tau\\pi\\pi\\pi$",
"Kpipi" : "$\\tau\\to\\nu_\\tau K\\pi\\pi$",
"KKpi" : "$\\tau\\to\\nu_\\tau KK\\pi$",
"3K" : "$\\tau\\to\\nu_\\tau K^+K^-K^-$",
"2pieta" : "$\\tau\\to\\nu_\\tau\\eta\\pi\\pi$",
"2pigamma" : "$\\tau\\to\\nu_\\tau\\gamma\\pi\\pi$",
"4pi" : "$\\tau\\to\\nu_\\tau4\\pi$",
"5pi" : "$\\tau\\to\\nu_\\tau5\\pi$",
"6pi" : "$\\tau\\to\\nu_\\tau6\\pi$",}
index.write("<ul>\n")
-
-
-
# two body
decays.write("<h2 id=\"3body\">Two Body</h2>\n")
index.write("<li> <a href=\"taus.html#2body\">Two Body:</a>\n")
for obs in ["1pi" ] :
decays.write("<h3 id=\"%s\">%s</h3>\n" % (obs,names[obs]))
index.write("<a href=\"taus.html#%s\">%s,<a/>\n" % (obs,names[obs]))
for val in ["data","MC"] :
if(val not in analyses["TauDecays"][obs] or len(analyses["TauDecays"][obs][val])==0) : continue
if(val=="data") : decays.write("<h4 id=\"%s_%s\">%s</h4>\n" % (obs,val,"Data"))
else : decays.write("<h4 id=\"%s_%s\">%s</h4>\n" % (obs,val,"Monte Carlo"))
writePlots2(analyses["TauDecays"][obs][val],decays)
# three body
decays.write("<h2 id=\"3body\">Three Body</h2>\n")
index.write("<li> <a href=\"taus.html#3body\">Three Body:</a>\n")
for obs in ["2pi", "Kpi", "KK", "lnu", "Keta" ] :
decays.write("<h3 id=\"%s\">%s</h3>\n" % (obs,names[obs]))
index.write("<a href=\"taus.html#%s\">%s,<a/>\n" % (obs,names[obs]))
for val in ["data","MC"] :
if(val not in analyses["TauDecays"][obs] or len(analyses["TauDecays"][obs][val])==0) : continue
if(val=="data") : decays.write("<h4 id=\"%s_%s\">%s</h4>\n" % (obs,val,"Data"))
else : decays.write("<h4 id=\"%s_%s\">%s</h4>\n" % (obs,val,"Monte Carlo"))
writePlots2(analyses["TauDecays"][obs][val],decays)
# four body
decays.write("<h2 id=\"4body\">Four Body</h2>\n")
index.write("<li> <a href=\"taus.html#4body\">Four Body:</a>\n")
for obs in ["3pi","Kpipi","KKpi","3K","2pieta","2pigamma" ] :
decays.write("<h3 id=\"%s\">%s</h3>\n" % (obs,names[obs]))
index.write("<a href=\"taus.html#%s\">%s,<a/>\n" % (obs,names[obs]))
for val in ["data","MC"] :
if(val not in analyses["TauDecays"][obs] or len(analyses["TauDecays"][obs][val])==0) : continue
if(val=="data") : decays.write("<h4 id=\"%s_%s\">%s</h4>\n" % (obs,val,"Data"))
else : decays.write("<h4 id=\"%s_%s\">%s</h4>\n" % (obs,val,"Monte Carlo"))
writePlots2(analyses["TauDecays"][obs][val],decays)
# five body
decays.write("<h2 id=\"5body\">Five Body</h2>\n")
- index.write("<li> <a href=\"taus.html#5body\">FIve Body:</a>")
+ index.write("<li> <a href=\"taus.html#5body\">Five Body:</a>")
for obs in ["4pi"] :
decays.write("<h3 id=\"%s\">%s</h3>\n" % (obs,names[obs]))
index.write("<a href=\"taus.html#%s\">%s,<a/>\n" % (obs,names[obs]))
for val in ["data","MC"] :
if(val not in analyses["TauDecays"][obs] or len(analyses["TauDecays"][obs][val])==0) : continue
if(val=="data") : decays.write("<h4 id=\"%s_%s\">%s</h4>\n" % (obs,val,"Data"))
else : decays.write("<h4 id=\"%s_%s\">%s</h4>\n" % (obs,val,"Monte Carlo"))
writePlots2(analyses["TauDecays"][obs][val],decays)
# six body
decays.write("<h2 id=\"6body\">Six and more Body</h2>\n")
index.write("<li> <a href=\"taus.html#6body\">Six Body:</a>")
for obs in ["5pi","6pi"] :
decays.write("<h3 id=\"%s\">%s</h3>\n" % (obs,names[obs]))
index.write("<a href=\"taus.html#%s\">%s,<a/>\n" % (obs,names[obs]))
for val in ["data","MC"] :
if(val not in analyses["TauDecays"][obs] or len(analyses["TauDecays"][obs][val])==0) : continue
if(val=="data") : decays.write("<h4 id=\"%s_%s\">%s</h4>\n" % (obs,val,"Data"))
else : decays.write("<h4 id=\"%s_%s\">%s</h4>\n" % (obs,val,"Monte Carlo"))
writePlots2(analyses["TauDecays"][obs][val],decays)
# footer
index.write("</ul>\n")
decays.write("</body>\n</html>")
decays.close()
def writeParticleDecays(particles,decays,index) :
+ global figures
for val in particles :
if val not in analyses["HadronDecays"] : continue
decays.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
index.write(" <a href=\"decays.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
if("Modes" in analyses["HadronDecays"][val] and len(analyses["HadronDecays"][val]["Modes"]) !=0) :
for mode,plots in analyses["HadronDecays"][val]["Modes"].items() :
decays.write("<h5>Mode: %s</h5>\n" % mode)
if("data" in plots) :
decays.write("<h5>Data</h5>\n")
writePlots2(plots["data"],decays)
if("MC" in plots) :
decays.write("<h5>Monte Carlo</h5>\n")
writePlots2(plots["MC"],decays)
# multiplicity dist
if("DistChargedMult" in analyses["HadronDecays"][val] and
len(analyses["HadronDecays"][val]["DistChargedMult"]) !=0) :
decays.write("<h5>Charged Particle Multplicity Distribution</h5>\n")
if("data" in analyses["HadronDecays"][val]["DistChargedMult"]) :
decays.write("<h5>Data</h5>\n")
writePlots2(analyses["HadronDecays"][val]["DistChargedMult"]["data"],decays)
if("MC" in analyses["HadronDecays"][val]["DistChargedMult"]) :
decays.write("<h5>Monte Carlo</h5>\n")
writePlots2(analyses["HadronDecays"][val]["DistChargedMult"]["MC"],decays)
# multiplicities
if("Mult" in analyses["HadronDecays"][val] and
len(analyses["HadronDecays"][val]["Mult"]) !=0) :
for prod,plots in sorted(analyses["HadronDecays"][val]["Mult"].items()):
if(len(plots)==0) : continue
if(prod!=0) :
decays.write("<h5>Multiplicity of %s</h5>\n" % particleNames[prod])
else :
decays.write("<h5>Multiplicity of Charged Particles</h5>\n")
writePlots2(plots,decays)
# spectra
if("Spectrum" in analyses["HadronDecays"][val] and
len(analyses["HadronDecays"][val]["Spectrum"]) !=0) :
for prod,plots in sorted(analyses["HadronDecays"][val]["Spectrum"].items()):
if(len(plots)==0) : continue
decays.write("<h5>Spectrum of %s</h5>\n" % particleNames[prod])
writePlots2(plots,decays)
# event shapes
if("Shapes" in analyses["HadronDecays"][val] and
len(analyses["HadronDecays"][val]["Shapes"]) !=0) :
decays.write("<h5>Events Shapes</h5>\n")
writePlots2(analyses["HadronDecays"][val]["Shapes"],decays)
# other dists
if("Other" in analyses["HadronDecays"][val] and
len(analyses["HadronDecays"][val]["Other"]) !=0) :
decays.write("<h5>Other Observables</h5>\n")
writePlots2(analyses["HadronDecays"][val]["Other"],decays)
+ # BR
+ if "BR" in analyses["HadronDecays"][val] :
+ for ana in analyses["HadronDecays"][val]["BR"] :
+ plots=[]
+ for name in figures :
+ if ana in name :
+ plots.append(name[name.find("/"):].replace(".dat",""))
+ if len(plots) !=0 :
+ decays.write("<h5>Branching Ratios</h5>\n")
+ writePlots2(plots,decays)
def writeDecays(index) :
decays=open(os.path.join(directory,"decays.html"),'w')
decays.write(header.format(title="Comparisions of Herwig7 and Hadronic Decay Data"))
index.write("<li> <a href=\"decays.html\">Hadron Decays</a>\n")
index.write(" <ul>\n")
# mesons
decays.write("<h2 id=\"MESONS\">Meson</h2>\n")
# light
decays.write("<h3 id=\"m_light\">Light, Unflavoured</h3>\n")
index.write("<li><a href=\"decays.html#m_light\">Light unflavoured mesons:<a/>\n")
writeParticleDecays(mLight,decays,index)
# charm
decays.write("<h3 id=\"m_charm\">Charm Mesons</h3>\n")
index.write("<li><a href=\"decays.html#m_charm\">Charm mesons:<a/>\n")
writeParticleDecays(mCharm,decays,index)
# bottom
decays.write("<h3 id=\"m_charm\">Bottom Mesons</h3>\n")
index.write("<li><a href=\"decays.html#m_charm\">Bottom mesons:<a/>\n")
writeParticleDecays(mBottom,decays,index)
# charmonium
decays.write("<h3 id=\"m_ccbar\">Charmonium</h3>\n")
index.write("<li><a href=\"decays.html#m_ccbar\">Charmonium:<a/>\n")
writeParticleDecays(mccbar,decays,index)
# bottomonium
decays.write("<h3 id=\"m_bbbar\">Bottomonium</h3>\n")
index.write("<li><a href=\"decays.html#m_bbbar\">Bottomonium:<a/>\n")
writeParticleDecays(mbbbar,decays,index)
+ # B_c
+ decays.write("<h3 id=\"m_bc\">$B_c$</h3>\n")
+ index.write("<li><a href=\"decays.html#m_bbbar\">$B_c$:<a/>\n")
+ writeParticleDecays(mbc,decays,index)
# hyperons
decays.write("<h3 id=\"b_strange\">Hyperons</h3>\n")
index.write("<li><a href=\"decays.html#b_strange\">Hyperons:<a/>\n")
writeParticleDecays(bStrange,decays,index)
- # hyperons
+ # charm baryons
decays.write("<h3 id=\"b_charm\">Charm Baryons</h3>\n")
index.write("<li><a href=\"decays.html#b_charm\">Charm Baryons:<a/>\n")
writeParticleDecays(bCharm,decays,index)
+ # bottom baryons
+ decays.write("<h3 id=\"b_bottom\">Bottom Baryons</h3>\n")
+ index.write("<li><a href=\"decays.html#b_bottom\">Bottom Baryons:<a/>\n")
+ writeParticleDecays(bBottom,decays,index)
# footer
index.write(" </ul>\n")
decays.write("</body>\n</html>")
decays.close()
def writeMult(index) :
index.write("<li> <a href=\"mult.html\">Identified Particle Multiplicities</a>\n")
mult=open(os.path.join(directory,"mult.html"),'w')
mult.write(header.format(title="Comparisions of Herwig7 and $e^+e^-$ Particle Multiplicities"))
# mesons
mult.write("<h2 id=\"MESONS\">Mesons</h2>\n")
mult.write("<h3 id=\"m_light\">Light, Unflavoured</h3>\n")
index.write("<ul>\n")
index.write("<li><a href=\"mult.html#m_light\">Light unflavoured mesons:<a/>\n")
# light
for val in mLight:
if(val not in analyses["Multiplicity"] or len(analyses["Multiplicity"][val])==0 ) : continue
index.write(" <a href=\"mult.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
mult.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
writePlots(analyses["Multiplicity"][val],mult)
mult.write("</div>\n")
index.write("<li><a href=\"mult.html#m_strange\">Strange mesons:<a/>\n")
mult.write("<h3 id=\"m_strange\">Strange</h3>\n")
# strange
for val in mStrange :
if(val not in analyses["Multiplicity"] or len(analyses["Multiplicity"][val])==0 ) : continue
index.write(" <a href=\"mult.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
mult.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
writePlots(analyses["Multiplicity"][val],mult)
mult.write("</div>\n")
# charm
index.write("<li><a href=\"mult.html#m_charm\">Charm mesons:<a/>\n")
mult.write("<h3 id=\"m_charm\">Charm</h3>\n")
for val in mCharm:
if(val not in analyses["Multiplicity"] or len(analyses["Multiplicity"][val])==0 ) : continue
index.write(" <a href=\"mult.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
mult.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
writePlots(analyses["Multiplicity"][val],mult)
mult.write("</div>\n")
# bottom
mult.write("<h3 id=\"m_bottom\">Bottom</h3>\n")
index.write("<li><a href=\"mult.html#m_bottom\">Bottom mesons:<a/>\n")
for val in mBottom :
if(val not in analyses["Multiplicity"] or len(analyses["Multiplicity"][val])==0 ) : continue
index.write(" <a href=\"mult.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
mult.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
writePlots(analyses["Multiplicity"][val],mult)
# charmonium
index.write("<li><a href=\"mult.html#m_ccbar\">$c\\bar{c}$ mesons:<a/>\n")
mult.write("<h3 id=\"m_ccbar\">$c\\bar{c}$</h3>\n")
for val in mccbar :
if(val not in analyses["Multiplicity"] or len(analyses["Multiplicity"][val])==0 ) : continue
index.write(" <a href=\"mult.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
mult.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
writePlots(analyses["Multiplicity"][val],mult)
# bottomonium
index.write("<li><a href=\"mult.html#m_bbbar\">$b\\bar{b}$ mesons:<a/>\n")
mult.write("<h3 id=\"m_bbbar\">$b\\bar{b}$</h3>\n")
for val in mbbbar :
if(val not in analyses["Multiplicity"] or len(analyses["Multiplicity"][val])==0 ) : continue
index.write(" <a href=\"mult.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
mult.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
writePlots(analyses["Multiplicity"][val],mult)
# baryons
mult.write("<h2 id=\"BARYONS\">Baryons</h2>\n")
# light unflavoured
index.write("<li><a href=\"mult.html#b_light\">Light unflavoured baryons:<a/>\n")
mult.write("<h3 id=\"b_light\">Light, Unflavoured</h3>\n")
for val in bLight:
if(val not in analyses["Multiplicity"] or len(analyses["Multiplicity"][val])==0 ) : continue
index.write(" <a href=\"mult.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
mult.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
writePlots(analyses["Multiplicity"][val],mult)
# hyperons
index.write("<li><a href=\"mult.html#b_strange\">Hyperons:<a/>\n")
mult.write("<h3 id=\"b_strange\">Hyperons</h3>\n")
for val in bStrange:
if(val not in analyses["Multiplicity"] or len(analyses["Multiplicity"][val])==0 ) : continue
index.write(" <a href=\"mult.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
mult.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
writePlots(analyses["Multiplicity"][val],mult)
# charm baryons
index.write("<li><a href=\"mult.html#b_charm\">Charm:<a/>\n")
mult.write("<h3 id=\"b_charm\">Charm Baryons</h3>\n")
for val in bCharm:
if(val not in analyses["Multiplicity"] or len(analyses["Multiplicity"][val])==0 ) : continue
index.write(" <a href=\"mult.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
mult.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
writePlots(analyses["Multiplicity"][val],mult)
# bottom
index.write("<li><a href=\"mult.html#b_bottom\">Bottom:<a/>\n")
mult.write("<h3 id=\"b_bottom\">Bottom Baryons</h3>\n")
for val in bBottom:
if(val not in analyses["Multiplicity"] or len(analyses["Multiplicity"][val])==0 ) : continue
index.write(" <a href=\"mult.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
mult.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
writePlots(analyses["Multiplicity"][val],mult)
# other
index.write("<li><a href=\"mult.html#other\">Other:<a/>\n")
mult.write("<h3 id=\"other\">Other</h3>\n")
for val in ["321/2212"]:
if(val not in analyses["Multiplicity"] or len(analyses["Multiplicity"][val])==0 ) : continue
index.write(" <a href=\"mult.html#%s\">%s,<a/>\n" % (val,particleNames[val]))
mult.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (val,particleNames[val]))
writePlots(analyses["Multiplicity"][val],mult)
# footer
index.write(" </ul>\n")
mult.write("</body>\n</html>")
mult.close()
def writeSpectrum(particles,index,ident) :
latexNames = { "x" : "Scaled Momentum/Energy",
"xi" : "Log of Scaled Momentum/Energy",
"p" : "Momentum/Energy",
"Ratio" : "Ratios of particle multiplicities",
"Other" : "Other distributions" }
for pdgId in particles:
if(pdgId not in analyses["IdentifiedParticle"]) : continue
sumL = len(analyses["IdentifiedParticle"][pdgId]["x"])+len(analyses["IdentifiedParticle"][pdgId]["p"])+\
len(analyses["IdentifiedParticle"][pdgId]["xi"])+len(analyses["IdentifiedParticle"][pdgId]["Ratio"])\
+len(analyses["IdentifiedParticle"][pdgId]["Other"])
if(sumL==0) : continue
# lines in html
ident.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (pdgId,particleNames[pdgId]))
index.write(" <a href=\"identified.html#%s\">%s,<a/>\n" % (pdgId,particleNames[pdgId]))
# plots
for val in ["x","p","xi","Ratio","Other"] :
if(len(analyses["IdentifiedParticle"][pdgId][val])==0) : continue
ident.write("<div style=\"float:none; overflow:auto; \">\n<h3 id=\"%s_%s\">%s</h3>\n" % (pdgId,val,latexNames[val]))
writePlots(analyses["IdentifiedParticle"][pdgId][val],ident)
ident.write("</div>\n")
def writePolar(particles,index,pol) :
latexNames = { "rho00" : "Longitudinal polarization",
"rho10" : "Off-diagonal $(\\rho_{10}$)",
"rho11" : "Transerve polarization",
"alpha" : "Asymmetry $\\alpha$",
"cos" : "$\\cos\\theta$ distributions",
"phi" : "Azimuthal Angle distributions",
"Other" : "Other distributions"}
for pdgId in particles:
if(pdgId not in analyses["Polarization"]) : continue
sumL = len(analyses["Polarization"][pdgId]["alpha"])+len(analyses["Polarization"][pdgId]["rho00"])+\
len(analyses["Polarization"][pdgId]["cos"])+len(analyses["Polarization"][pdgId]["phi"])+\
len(analyses["Polarization"][pdgId]["rho10"])+len(analyses["Polarization"][pdgId]["rho11"])
if(sumL==0) : continue
# lines in html
pol.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"%s\">%s</h4>\n" % (pdgId,particleNames[pdgId]))
index.write(" <a href=\"polarization.html#%s\">%s,<a/>\n" % (pdgId,particleNames[pdgId]))
# plots
for val in ["rho00","alpha","rho10","rho11","cos","phi","Other"] :
if(len(analyses["Polarization"][pdgId][val])==0) : continue
pol.write("<div style=\"float:none; overflow:auto; \">\n<h3 id=\"%s_%s\">%s</h3>\n" % (pdgId,val,latexNames[val]))
writePlots(analyses["Polarization"][pdgId][val],pol)
pol.write("</div>\n")
# output the identified particle plots
def writeIdentified(index) :
ident=open(os.path.join(directory,"identified.html"),'w')
# header for page
ident.write(header.format(title="Comparisions of Herwig7 and $e^+e^-$ Identified Particle Spectra"))
# line for index
index.write("<li> <a href=\"identified.html\">Identified Particle Spectra</a>\n")
index.write("<ul>\n")
# photons
ident.write("<h2 id=\"gamma\">Photons</h2>\n")
index.write("<li> <a href=\"identified.html#gamma\">Photons:<a/>\n")
writeSpectrum([22],index,ident)
ident.write("<h2 id=\"MESONS\">Mesons</h2>\n")
# Light unflavoured mesons
ident.write("<h3 id=\"m_light\">Light, Unflavoured</h3>\n")
index.write("<li><a href=\"identified.html#m_light\">Light unflavoured mesons:<a/>\n")
writeSpectrum(mLight,index,ident)
# Strange mesons
ident.write("<h3 id=\"m_strange\">Strange</h3>\n")
index.write("<li><a href=\"identified.html#m_strange\">Strange mesons:<a/>\n")
writeSpectrum(mStrange,index,ident)
# charm mesons
ident.write("<h3 id=\"m_charm\">Charm</h3>\n")
index.write("<li><a href=\"identified.html#m_charm\">Charm mesons:<a/>\n")
writeSpectrum(mCharm,index,ident)
# charmonium
ident.write("<h3 id=\"m_charm\">Charmonium</h3>\n")
index.write("<li><a href=\"identified.html#m_charm\">Charmonium:<a/>\n")
writeSpectrum(mccbar,index,ident)
# Baryons
ident.write("<h2 id=\"BARYONS\">Baryons</h2>\n")
# light baryons
ident.write("<h3 id=\"b_light\">Light, Unflavoured</h3>\n")
index.write("<li><a href=\"identified.html#b_light\">Light unflavoured baryons:<a/>\n")
writeSpectrum(bLight,index,ident)
# hyperons
ident.write("<h3 id=\"b_strange\">Hyperons</h3>\n")
index.write("<li><a href=\"identified.html#b_strange\">Hyperons:<a/>\n")
writeSpectrum(bStrange,index,ident)
# charm baryons
ident.write("<h3 id=\"b_charm\">Charm Baryons</h3>\n")
index.write("<li><a href=\"identified.html#b_charm\">Charm baryons:<a/>\n")
# loop over particles
writeSpectrum(bCharm,index,ident)
# other
ident.write("<h3 id=\"other\">Other</h3>\n")
index.write("<li><a href=\"identified.html#other\">Other:<a/>\n")
# loop over particles
writeSpectrum(["321/2212"],index,ident)
# bottom fragmentation
ident.write("<h2 id=\"b_frag\">Bottom Fragmentation Function</h2>\n")
index.write("<li><a href=\"identified.html#b_frag\">Bottom Fragmentation Function:<a/>\n")
for val in ["weak","lead","weak_mean","lead_mean"] :
if val=="weak" :
name="Weakly Decaying B hadron"
name2="Weakly Decaying"
elif val=="lead" :
name="Leading Decaying B hadron"
name2="Leading"
elif val=="weak_mean":
name="Weakly Decaying B hadron (average)"
name2="Weakly Decaying (average)"
elif val=="lead_mean" :
name="Leading Decaying B hadron (average)"
name2="Leading (average)"
ident.write("<div style=\"float:none; overflow:auto; \">\n<h3 id=\"%s\">%s</h3>\n" % (val,name))
index.write("<a href=\"identified.html#%s\">%s,<a/>\n" % (val,name2))
writePlots2(analyses["IdentifiedParticle"][511][val],ident)
ident.write("</div>\n")
writeSpectrum([513],index,ident)
# footer
index.write(" </ul>\n")
ident.write("</body>\n</html>")
ident.close()
def writeFlavour(index) :
flavour=open(os.path.join(directory,"flavour.html"),'w')
flavour.write(header.format(title="Comparisions of Herwig7 and Flavour Separated $e^+e^-$ Data"))
index.write("<li> <a href=\"flavour.html\">Flavour Separated</a>\n")
index.write(" <ul>\n")
# total multiplicity
flavour.write("<h2 id=\"mult\">Charged Particle Multiplicity</h2>\n")
index.write("<li> <a href=\"flavour.html#mult\">Total Charged Multiplicity: </a> \n")
titles={ 1 : "Light (uds)", 2 : "Light (udsc)", 4 : "Charm" , 5 : "Bottom", 41 : "Charm-Light difference", 51 : "Charm-bottom difference"}
lFormat="""<div style=\"float:none; overflow:auto; width:100%\">\n<{hlevel} id=\"{tag}\">{name}</{hlevel}>\n"""
for flav in [1,4,5,41,51] :
if(flav in analyses["Charged"]["TotalChargedMult"] and
len(analyses["Charged"]["TotalChargedMult"][flav])!=0) :
if(flav!=51) : index.write(" <a href=\"flavour.html#mult_%s\">%s,<a/>\n" % (flav,titles[flav]) )
else : index.write(" <a href=\"flavour.html#mult_%s\">%s.<a/>\n" % (flav,titles[flav]) )
flavour.write(lFormat.format(hlevel="h3",tag="mult_%s"%flav,name=titles[flav]))
writePlots(analyses["Charged"]["TotalChargedMult"][flav],flavour)
flavour.write("</div>\n")
# multiplicity dist
flavour.write("<h2 id=\"multdist\">Charged Particle Multiplicity Distribution</h2>\n")
index.write("<li> <a href=\"flavour.html#multdist\">Charged Particle Multiplicity Distribution</a>\n")
for flav in [1,2,4,5] :
if(flav in analyses["Charged"]["DistChargedMult"] and
len(analyses["Charged"]["DistChargedMult"][flav])!=0) :
if(flav!=5) : index.write(" <a href=\"flavour.html#multdist_%s\">%s,<a/>\n" % (flav,titles[flav]) )
else : index.write(" <a href=\"flavour.html#multdist_%s\">%s.<a/>\n" % (flav,titles[flav]) )
flavour.write(lFormat.format(hlevel="h3",tag="multdist_%s"%flav,name=titles[flav]))
writePlots(analyses["Charged"]["DistChargedMult"][flav],flavour)
flavour.write("</div>\n")
# event shapes
flavour.write("<h2 id=\"EVENT\">Event Shapes</h2>\n")
index.write("<li> <a href=\"flavour.html#event\">Event Shapes: </a> \n")
index.write("<ul>")
# thrust
eventShapes = {"T" : "Thrust" , "HeavyJetMass" : "Heavy Jet Mass", "BT" : "Total Jet Broadening",
- "BW" : "Wide Jet Broadening", "C" : "C", "D" : "D"}
- for obs in ["T", "HeavyJetMass","BT","BW","C","D"] :
+ "BW" : "Wide Jet Broadening", "C" : "C", "D" : "D", "y23" : "y23"}
+ for obs in ["T", "HeavyJetMass","BT","BW","C","D","y23"] :
flavour.write(lFormat.format(hlevel="h3",tag="event_%s"%obs,name=eventShapes[obs]))
index.write(" <li> <a href=\"flavour.html#event_%s\">%s:<a/>\n" % (obs,eventShapes[obs]))
for flav in [1,2,4,5] :
if(flav in analyses["EventShapesFlavour"][obs] and
len(analyses["EventShapesFlavour"][obs][flav])!=0) :
if(flav!=5) : index.write(" <a href=\"flavour.html#event_%s_%s\">%s,<a/>\n" % (obs,flav,titles[flav]) )
else : index.write(" <a href=\"flavour.html#event_%s_%s\">%s.<a/>\n" % (obs,flav,titles[flav]) )
flavour.write(lFormat.format(hlevel="h4",tag="event_%s_%s"%(obs,flav),name=titles[flav]))
writePlots(analyses["EventShapesFlavour"][obs][flav],flavour)
flavour.write("</div>\n")
flavour.write("</div>\n")
index.write("</ul>")
# spectrum
flavour.write("<h2 id=\"spectrum\">Charged Particle Spectra</h2>\n")
index.write("<li> <a href=\"flavour.html#spectrum\">Charged Particle Spectra: </a> \n")
for flav in [1,2,4,5] :
if(flav in analyses["Charged"]["ChargedSpectrum"] and
len(analyses["Charged"]["ChargedSpectrum"][flav])!=0) :
if(flav!=5) : index.write(" <a href=\"flavour.html#spectra_%s\">%s,<a/>\n" % (flav,titles[flav]) )
else : index.write(" <a href=\"flavour.html#spectra_%s\">%s.<a/>\n" % (flav,titles[flav]) )
flavour.write(lFormat.format(hlevel="h3",tag="spectra_%s"%flav,name=titles[flav]))
for obs in ["x","xi","Other"] :
if obs== "x" : name="Scaled Momentum"
elif obs=="xi" : name="Log of the scaled Momentum"
else : name="Other distributions"
if(obs not in analyses["Charged"]["ChargedSpectrum"][flav]) : continue
flavour.write(lFormat.format(hlevel="h4",tag="spectra_%s_%s"% (flav,obs),name=name))
writePlots(analyses["Charged"]["ChargedSpectrum"][flav][obs],flavour)
flavour.write("</div>\n")
flavour.write("</div>\n")
# multiplicities
flavour.write("<h2 id=\"mults\">Identified Particle Multiplicities</h2>\n")
index.write("<li> <a href=\"flavour.html#mults\">Identified Particle Multiplicities: </a> \n")
for flav in [1,4,5,41,51] :
if(flav!=51) : index.write(" <a href=\"flavour.html#mults_%s\">%s,<a/>\n" % (flav,titles[flav]) )
else : index.write(" <a href=\"flavour.html#mults_%s\">%s.<a/>\n" % (flav,titles[flav]) )
flavour.write(lFormat.format(hlevel="h3",tag="mults_%s"%flav,name=titles[flav]))
for val in mLight+mStrange+bLight+bStrange+["321/2212"] :
if(val not in analyses["MultiplicityFlavour"] or
flav not in analyses["MultiplicityFlavour"][val] or
len(analyses["MultiplicityFlavour"][val][flav])==0) : continue
flavour.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"f_%s_%s\">%s</h4>\n" % (flav,val,particleNames[val]))
writePlots(analyses["MultiplicityFlavour"][val][flav],flavour)
flavour.write("</div>\n")
# identified particle specrtra
flavour.write("<h2 id=\"ident\">Identified Particle Spectra</h2>\n")
index.write("<li> <a href=\"flavour.html#ident\">Identified Particle Spectra: </a> \n")
titles[41] = "Ratio Charm to Light"
titles[51] = "Ratio Bottom to Light"
obsName = { "x" : "Scaled Momentum",
"xi" : "Log of Scaled Momentum",
"Ratio" : "Ratios of Particle Multiplicities",
"Other" : "Other Distributions" }
for flav in [1,4,5,41,51] :
if(flav!=51) : index.write(" <a href=\"flavour.html#identf_%s\">%s,<a/>\n" % (flav,titles[flav]) )
else : index.write(" <a href=\"flavour.html#identf_%s\">%s.<a/>\n" % (flav,titles[flav]) )
flavour.write(lFormat.format(hlevel="h3",tag="identf_%s"%flav,name=titles[flav]))
for val in [111,211,311,321,313,333,2212,3122,413,"321/2212"] :
if(val not in analyses["IdentifiedParticleFlavour"]) : continue
if(flav not in analyses["IdentifiedParticleFlavour"][val]) : continue
aSum=0
for key,temp in analyses["IdentifiedParticleFlavour"][val][flav].items():
aSum+=len(temp)
if(aSum==0) : continue
flavour.write("<div style=\"float:none; overflow:auto; \">\n<h4 id=\"f_%s_%s\">%s</h4>\n" % (flav,val,particleNames[val]))
for obs in ["x","xi","Ratio","Other"] :
if(obs not in analyses["IdentifiedParticleFlavour"][val][flav] or
len(analyses["IdentifiedParticleFlavour"][val][flav][obs])==0) : continue
flavour.write("<div style=\"float:none; overflow:auto; \">\n<h5 id=\"f_%s_%s_%s\">%s</h5>\n" % (flav,val,obs,obsName[obs]))
writePlots(analyses["IdentifiedParticleFlavour"][val][flav][obs],flavour)
flavour.write("</div>\n")
flavour.write("</div>\n")
# footer
index.write("</ul>\n")
flavour.write("</body>\n</html>")
flavour.close()
def writeCharged(index) :
# headers
charged=open(os.path.join(directory,"charged.html"),'w')
charged.write(header.format(title="Comparisions of Herwig7 and $e^+e^-$ Data on Charged Particles"))
index.write("<li> <a href=\"charged.html\">Charged Particles</a>\n")
index.write("<ul>\n")
# total multiplicity
index.write("<li> <a href=\"charged.html#mult\">Total Charged Multiplicity</a> \n")
charged.write("<h2 id=\"mult\">Charged Particle Multiplicity</h2>\n")
charged.write("<div style=\"float:none; overflow:auto; width:100%\">\n")
writePlots(analyses["Charged"]["TotalChargedMult"][0],charged)
charged.write("</div>\n")
# with cuts
charged.write("<h2 id=\"mult_c\">Charged Particle Multiplicity, With Cuts</h2>\n")
index.write("<a href=\"charged.html#mult_c\">(with cuts)</a> \n")
charged.write("<div style=\"float:none; overflow:auto; width:100%\">\n")
writePlots(analyses["Charged"]["TotalChargedMult"]["C"],charged)
charged.write("</div>\n")
# multiplicity dist
charged.write("<h2 id=\"multdist\">Charged Particle Multiplicity Distribution</h2>\n")
index.write("<li> <a href=\"charged.html#multdist\">Charged Multiplicity Distribution</a> \n")
charged.write("<div style=\"float:none; overflow:auto; width:100%\">\n")
writePlots(analyses["Charged"]["DistChargedMult"][0],charged)
charged.write("</div>\n")
index.write("<a href=\"charged.html#multdist_c\">(with cuts)</a> \n")
charged.write("<h2 id=\"multdist_c\">Charged Particle Multiplicity Distributions, with cuts</h2>\n")
charged.write("<div style=\"float:none; overflow:auto; width:100%\">\n")
writePlots(analyses["Charged"]["DistChargedMult"]["C"],charged)
charged.write("</div>\n")
# spectra
index.write("<li> <a href=\"charged.html#spectra\">Charged Spectra</a> \n")
charged.write("<h2 id=\"spectra\">Charged Particle Spectra</h2>\n")
for val2 in [0,"C"] :
if(val2=="C") :
charged.write("<h3 id=\"spectra_c\">With cuts</h2>\n")
index.write("<a href=\"charged.html#spectra_c\">(with cuts)</a> \n")
for val in ["x","p","xi","Other"] :
if(val not in analyses["Charged"]["ChargedSpectrum"][val2] or
len(analyses["Charged"]["ChargedSpectrum"][val2][val])==0) : continue
if(val=="x") :
charged.write("<h4 id=\"spectra\">Scaled Momentum</h2>\n")
elif(val=="p") :
charged.write("<h4 id=\"spectra\">Momentum</h2>\n")
elif(val=="xi") :
charged.write("<h4 id=\"spectra\">Log of the Scaled Momentum</h2>\n")
elif(val=="Other") :
charged.write("<h4 id=\"spectra\">Other Distributions</h2>\n")
charged.write("<div style=\"float:none; overflow:auto; width:100%\">\n")
writePlots(analyses["Charged"]["ChargedSpectrum"][val2][val],charged)
charged.write("</div>\n")
# with respect to axes
lFormat="""<div style=\"float:none; overflow:auto; width:100%\">\n<{hlevel} id=\"{tag}\">{name}</{hlevel}>\n"""
for axis in ["Thrust","Sphericity"] :
if axis=="Thrust" :
abbrev = "T"
else :
abbrev = "S"
charged.write("<h2 id=\"%s\">Charged Particle Distribution w.r.t the %s axis</h2>\n" % (abbrev,axis))
index.write("<li> <a href=\"charged.html#%s\">Distributions w.r.t %s axis:</a> \n" % (abbrev,axis))
# rapidity
index.write(" <a href=\"charged.html#%srap\">rapidity,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%srap"%abbrev,name="Rapidity"))
writePlots(analyses["Charged"]["ChargedRapidity%s"%axis],charged)
charged.write("</div>\n")
# pT in
index.write(" <a href=\"charged.html#%sptin\">$p_\\perp^{\\text{in}}$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%sptin"%abbrev,name="$p_\\perp^{\\text{in}}$"))
writePlots(analyses["Charged"]["ChargedpTIn%s"%axis],charged)
charged.write("</div>\n")
# pT out
index.write(" <a href=\"charged.html#%sptout\">$p_\\perp^{\\text{out}}$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%sptout"%abbrev,name="$p_\\perp^{\\text{out}}$"))
writePlots(analyses["Charged"]["ChargedpTOut%s"%axis],charged)
charged.write("</div>\n")
# pL
if("ChargedpL%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedpL%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%spL\">$p_\\parallel$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%spL"%abbrev,name="$p_\\parallel$"))
writePlots(analyses["Charged"]["ChargedpL%s"%axis],charged)
charged.write("</div>\n")
# pT
if("ChargedpT%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedpT%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%spt\">$p_\\perp$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%spt"%abbrev,name="$p_\\perp$"))
writePlots(analyses["Charged"]["ChargedpT%s"%axis],charged)
charged.write("</div>\n")
# pT average
if("ChargedAveragepT%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedAveragepT%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%sptaver\">$\langle p_\\perp\\rangle$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%sptaver"%abbrev,name="$\langle p_\\perp\\rangle$"))
writePlots(analyses["Charged"]["ChargedAveragepT%s"%axis],charged)
charged.write("</div>\n")
# pT2 average
if("ChargedAveragepT2%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedAveragepT2%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%spt2aver\">$\langle p^2_\\perp\\rangle$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%spt2aver"%abbrev,name="$\langle p^2_\\perp\\rangle$"))
writePlots(analyses["Charged"]["ChargedAveragepT2%s"%axis],charged)
charged.write("</div>\n")
# pT sum
if("ChargedSumpT%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedSumpT%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%sptsum\">$\sum p_\\perp$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%sptsum"%abbrev,name="$\sum p_\\perp$"))
writePlots(analyses["Charged"]["ChargedSumpT%s"%axis],charged)
charged.write("</div>\n")
# pT2 sum
if("ChargedSumpT2%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedSumpT2%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%sptsum\">$\sum p^2_\\perp$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%sptsum"%abbrev,name="$\sum p^2_\\perp$"))
writePlots(analyses["Charged"]["ChargedSumpT2%s"%axis],charged)
charged.write("</div>\n")
# pT vs xp
if("ChargedpTvsxp%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedpTvsxp%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%spt\">$p_\\perp$ vs $x_p$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%spt"%abbrev,name="$p_\\perp$ vs $x_p$"))
writePlots(analyses["Charged"]["ChargedpTvsxp%s"%axis],charged)
charged.write("</div>\n")
# pT out vs xp
if("ChargedpTOutvsxp%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedpTOutvsxp%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%spt\">$p^{\\text{out}}_\\perp$ vs $x_p$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%spt"%abbrev,name="$p^{\\text{out}}_\\perp$ vs $x_p$"))
writePlots(analyses["Charged"]["ChargedpTOutvsxp%s"%axis],charged)
charged.write("</div>\n")
# xF
if("ChargedxF%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedxF%s"%axis])!=0) :
- index.write(" <a href=\"charged.html#%sxF\">$x_F$.<a/>\n" %abbrev)
+ index.write(" <a href=\"charged.html#%sxF\">$x_F$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%sxF"%abbrev,name="$x_F$"))
writePlots(analyses["Charged"]["ChargedxF%s"%axis],charged)
charged.write("</div>\n")
# pT2
if("ChargedpT2%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedpT2%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%spt2\">$p^2_\\perp$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%spt2"%abbrev,name="$p^2_\\perp$"))
writePlots(analyses["Charged"]["ChargedpT2%s"%axis],charged)
charged.write("</div>\n")
# average ptin
+ if("ChargedAveragepTIn%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedAveragepTIn%s"%axis])!=0) :
+ index.write(" <a href=\"charged.html#%saverptin\">$\langle p_{\\perp\\text{in}}\\rangle$,<a/>\n" %abbrev)
+ charged.write(lFormat.format(hlevel="h3",tag="%saverptin"%abbrev,name="$\langle p_{\\perp\\text{in}}\\rangle$"))
+ writePlots(analyses["Charged"]["ChargedAveragepTIn%s"%axis],charged)
+ charged.write("</div>\n")
+ # average ptin^2
if("ChargedAveragepT2in%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedAveragepT2in%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%saverpt2in\">$\langle p^2_{\\perp\\text{in}}\\rangle$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%saverpt2in"%abbrev,name="$\langle p^2_{\\perp\\text{in}}\\rangle$"))
writePlots(analyses["Charged"]["ChargedAveragepT2in%s"%axis],charged)
charged.write("</div>\n")
- # average ptout
+ # average ptin
+ if("ChargedAveragepTOut%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedAveragepTOut%s"%axis])!=0) :
+ index.write(" <a href=\"charged.html#%saverptout\">$\langle p_{\\perp\\text{out}}\\rangle$,<a/>\n" %abbrev)
+ charged.write(lFormat.format(hlevel="h3",tag="%saverptout"%abbrev,name="$\langle p_{\\perp\\text{out}}\\rangle$"))
+ writePlots(analyses["Charged"]["ChargedAveragepTOut%s"%axis],charged)
+ charged.write("</div>\n")
+ # average ptout^2
if("ChargedAveragepT2out%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedAveragepT2out%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%saverpt2out\">$\langle p^2_{\\perp\\text{out}}\\rangle$,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%saverpt2out"%abbrev,name="$\langle p^2_{\\perp\\text{out}}\\rangle$"))
writePlots(analyses["Charged"]["ChargedAveragepT2out%s"%axis],charged)
charged.write("</div>\n")
# charged flow
if("ChargedFlow%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedFlow%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%sFlow\">Charge Flow,<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%sFlow"%abbrev,name="Charge Flow"))
writePlots(analyses["Charged"]["ChargedFlow%s"%axis],charged)
charged.write("</div>\n")
# energy flow
if("ChargedEnergyFlow%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedEnergyFlow%s"%axis])!=0) :
index.write(" <a href=\"charged.html#%sEnergyFlow\">Energy Flow.<a/>\n" %abbrev)
charged.write(lFormat.format(hlevel="h3",tag="%sEnergyFlow"%abbrev,name="Energy Flow"))
writePlots(analyses["Charged"]["ChargedEnergyFlow%s"%axis],charged)
charged.write("</div>\n")
+ # average N
+ if("ChargedMultvs%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedMultvs%s"%axis])!=0) :
+ index.write(" <a href=\"charged.html#%saverN\">$\langle N_{\\text{charged}}\\rangle$,<a/>\n" %abbrev)
+ charged.write(lFormat.format(hlevel="h3",tag="%saverN"%abbrev,name="$\langle N_{\\text{charged}}\\rangle$"))
+ writePlots(analyses["Charged"]["ChargedMultvs%s"%axis],charged)
+ charged.write("</div>\n")
+ # average x
+ if("ChargedAveragex%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedAveragex%s"%axis])!=0) :
+ index.write(" <a href=\"charged.html#%saverptin\">$\langle x\\rangle$,<a/>\n" %abbrev)
+ charged.write(lFormat.format(hlevel="h3",tag="%saverptin"%abbrev,name="$\langle x\\rangle$"))
+ writePlots(analyses["Charged"]["ChargedAveragex%s"%axis],charged)
+ charged.write("</div>\n")
+ # average y
+ if("ChargedAveragey%s"%axis in analyses["Charged"] and len(analyses["Charged"]["ChargedAveragey%s"%axis])!=0) :
+ index.write(" <a href=\"charged.html#%saverptin\">$\langle y\\rangle$.<a/>\n" %abbrev)
+ charged.write(lFormat.format(hlevel="h3",tag="%saverptin"%abbrev,name="$\langle y\\rangle$"))
+ writePlots(analyses["Charged"]["ChargedAveragey%s"%axis],charged)
+ charged.write("</div>\n")
# footer
index.write(" </ul>\n")
charged.write("</body>\n</html>")
charged.close()
def writeJets(index) :
jets=open(os.path.join(directory,"jets.html"),'w')
jets.write(header.format(title="Comparisions of Herwig7 and $e^+e^-$ Jet Data"))
index.write("<li> <a href=\"jets.html\">Jets</a>\n")
index.write("<ul>\n")
# fractions
jets.write("<h2 id=\"FRACTION\">Jet Fractions</h2>\n")
index.write("<li> <a href=\"jets.html#FRACTION\">Jet Fractions:</a> \n")
lFormat="""<div style=\"float:none; overflow:auto; width:100%\">\n<{hlevel} id=\"{tag}\">{name}</{hlevel}>\n"""
for i in range(1,7) :
if(i<6) : index.write(" <a href=\"jets.html#%sjet\">%s jet,<a/>\n" % (i,i))
else : index.write(" <a href=\"jets.html#%sjet\">%s jet.<a/>\n" % (i,i))
jets .write(lFormat.format(hlevel="h3",tag ="%sjet" % i,name ="%s Jet Fraction" % i))
jets .write(lFormat.format(hlevel="h4",tag ="%sjet_dur" % i,name ="%s Jet Fraction (Durham)" % i))
writePlots(analyses["EventShapes"]["%sjet_dur" % i],jets)
jets.write("</div>\n")
jets .write(lFormat.format(hlevel="h4",tag ="%sjet_jade" % i,name ="%s Jet Fraction (JADE)" % i))
writePlots(analyses["EventShapes"]["%sjet_jade" % i],jets)
jets.write("</div>\n")
+ jets .write(lFormat.format(hlevel="h4",tag ="%sjet_cam" % i,name ="%s Jet Fraction (Cambridge)" % i))
+ writePlots(analyses["EventShapes"]["%sjet_cam" % i],jets)
+ jets.write("</div>\n")
jets.write("</div>\n")
# differential jet rates
index.write("<li> <a href=\"jets.html#DRATE\">Differential jet rates:</a> \n")
jets.write("<h2 id=\"DRATE\">Differential Jet Rates</h2>\n")
for i in range(1,6) :
yval="%s%s" % (i,i+1)
if(i!=5) : index.write(" <a href=\"jets.html#y%s\">$y_{%s}$,<a/>\n" %(yval,yval))
else : index.write(" <a href=\"jets.html#y%s\">$y_{%s}$.<a/>\n" %(yval,yval))
jets .write(lFormat.format(hlevel="h3",tag ="y%s" % yval,name ="$y_{%s}$" % yval))
if(len(analyses["EventShapes"]["y%s_dur" % yval])!=0) :
jets .write(lFormat.format(hlevel="h4",tag ="y%s_dur" % yval,name ="$y_{%s}$ (Durham)" % yval))
writePlots(analyses["EventShapes"]["y%s_dur" % yval],jets)
jets.write("</div>\n")
if(len(analyses["EventShapes"]["y%s_jade" % yval])!=0) :
jets .write(lFormat.format(hlevel="h4",tag ="y%s_jade" % yval,name ="$y_{%s}$ (JADE)" % yval))
writePlots(analyses["EventShapes"]["y%s_jade" % yval],jets)
jets.write("</div>\n")
+ if(len(analyses["EventShapes"]["y%s_cam" % yval])!=0) :
+ jets .write(lFormat.format(hlevel="h4",tag ="y%s_cam" % yval,name ="$y_{%s}$ (Cambridge)" % yval))
+ writePlots(analyses["EventShapes"]["y%s_cam" % yval],jets)
+ jets.write("</div>\n")
jets.write("</div>\n")
# 4 jet angles
index.write("<li> <a href=\"jets.html#4JET\">Four jet angles:</a> \n")
jets.write("<h2 id=\"4JET\">Four Jet Angles</h2>\n")
for val in ["BZ","KSW","NR","alpha34"] :
if val == "BZ" : title="Bengtsson-Zerwas angle"
elif val == "KSW" : title="Korner-Schierholz-Willrodt angle"
elif val == "NR" : title="Modified Nachtmann-Reiter angle"
elif val == "alpha34" : title="$\\alpha_{34}$"
if(val!="alpha34") : index.write(" <a href=\"jets.html#%s\">%s,<a/>\n" %(val,title))
else : index.write(" <a href=\"jets.html#%s\">%s.<a/>\n" %(val,title))
jets .write(lFormat.format(hlevel="h3",tag=val,name=title))
writePlots(analyses["FourJet"][val],jets)
# footer
index.write(" </ul>\n")
jets.write("</div>\n")
jets.write("</body>\n</html>")
jets.close()
def writeEventShapes(index) :
lFormat="""<div style=\"float:none; overflow:auto; width:100%\">\n<{hlevel} id=\"{tag}\">{name}</{hlevel}>\n"""
index.write("<ul>\n")
index.write("<li> <a href=\"event.html\">Event Shapes</a>\n")
index.write("<ul>\n")
event=open(os.path.join(directory,"event.html"),'w')
event.write(header.format(title="Comparisions of Herwig7 and $e^+e^-$ Event Shape Data"))
# thrust and related
event.write("<h2 id=\"THRUST\">Thrust and Related Variables</h2>\n")
index.write("<li> <a href=\"event.html#THRUST\">Thrust related:</a> \n")
for obs in ["T","Major","Minor","O"]:
title=obs
if(title=="T") : title="Thrust"
elif(title=="O") : title="Oblateness"
event.write(lFormat.format(hlevel="h3",tag=obs,name=title))
index.write(" <a href=\"event.html#%s\">%s,<a/>\n" %(obs,title))
writePlots(analyses["EventShapes"][obs],event)
event.write("</div>\n")
# sphericity and related
index.write("<li> <a href=\"event.html#SPHERICITY\">Sphericity related:</a> \n")
event.write("<h2 id=\"SPHERICITY\">Sphericity and Related Variables</h2>\n")
for obs in ["S","P","A","Qx","Q21"]:
if obs == "S" : title="Sphericity"
elif obs == "P" : title="Planarity"
elif obs == "A" : title="Aplanarity"
elif obs == "Qx" : title="$Q_x$"
elif obs == "Q21": title="$Q_2-Q_1$"
event.write(lFormat.format(hlevel="h3",tag=obs,name=title))
index.write(" <a href=\"event.html#%s\">%s,<a/>\n" %(obs,title))
writePlots(analyses["EventShapes"][obs],event)
event.write("</div>\n")
# jet masses
event.write("<h2 id=\"MASSES\">Jet Masses</h2>\n")
index.write("<li> <a href=\"event.html#MASSES\">Jet Masses:</a> \n")
for obs in ["HeavyJetMass","LightJetMass","TotalJetMass","JetMassDifference"]:
if obs == "HeavyJetMass" : title="Heavy Jet Mass"
elif obs == "LightJetMass" : title="Light Jet Mass"
elif obs == "TotalJetMass" : title="Total Jet Mass"
elif obs == "JetMassDifference" : title="Jet Mass Difference"
event.write(lFormat.format(hlevel="h3",tag=obs,name=title))
index.write(" <a href=\"event.html#%s\">%s,<a/>\n" %(obs,title))
writePlots(analyses["EventShapes"][obs],event)
event.write("</div>\n")
# EEC and AEEC
event.write("<h2 id=\"eec\">Energy-Energy Correlations</h2>\n")
index.write("<li> <a href=\"event.html#eec\">Energy-Energy Correlations:</a> \n")
- for obs in ["EEC","AEEC"]:
+ for obs in ["EEC","AEEC","JCEF"]:
if obs == "EEC" : title="Energy-Energy Correlation"
elif obs == "AEEC" : title="Energy-Energy Asymmetry Correlation"
+ elif obs == "JCEF" : title="Jet-Cone Energy Fraction"
event.write(lFormat.format(hlevel="h3",tag=obs,name=title))
index.write(" <a href=\"event.html#%s\">%s,<a/>\n" %(obs,title))
writePlots(analyses["EventShapes"][obs],event)
event.write("</div>\n")
# jet broadening
event.write("<h2 id=\"JB\">Jet Broadenings</h2>\n")
index.write("<li> <a href=\"event.html#JB\">Jet Broadening:</a> \n")
for obs in ["BT","BW","BN","Bdiff"]:
if obs == "BT" : title="Total Jet Broadening"
elif obs == "BW" : title="Wide Jet Broadening"
elif obs == "BN" : title="Narrow Jet Broadening"
elif obs == "Bdiff" : title="Difference of Jet Broadenings"
event.write(lFormat.format(hlevel="h3",tag=obs,name=title))
index.write(" <a href=\"event.html#%s\">%s,<a/>\n" %(obs,title))
writePlots(analyses["EventShapes"][obs],event)
event.write("</div>\n")
# C and D
event.write("<h2 id=\"CD\">C and D parameters</h2>\n")
index.write("<li> <a href=\"event.html#CD\">C and D parameters:</a> \n")
for obs in ["C","D"]:
title= "%s-parameter" % obs
event.write(lFormat.format(hlevel="h3",tag=obs,name=title))
index.write(" <a href=\"event.html#%s\">%s,<a/>\n" %(obs,title))
writePlots(analyses["EventShapes"][obs],event)
event.write("</div>\n")
# moments of event shapes
event.write("<h2 id=\"MOMENT\">Moments of Event Shapes</h2>\n")
index.write("<li> <a href=\"event.html#MOMENT\">Moments:</a> \n")
for val in ["Moment_T","Moment_M","Moment_m","Moment_O","Moment_H","Moment_L",
"Moment_BT","Moment_BW","Moment_BN","Moment_C","Moment_S","Moment_y"] :
if(val=="Moment_T") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_thrust\">Thrust</h3>\n")
index.write(" <a href=\"event.html#m_thrust\">thrust,<a/>\n")
elif(val=="Moment_M") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_major\">Thrust Major</h3>\n")
index.write(" <a href=\"event.html#m_major\">major,<a/>\n")
elif(val=="Moment_m") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_minor\">Thrust Minor</h3>\n")
index.write(" <a href=\"event.html#m_minor\">minor,<a/>\n")
elif(val=="Moment_O") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_O\">Oblateness</h3>\n")
index.write(" <a href=\"event.html#m_O\">oblateness,<a/>\n")
elif(val=="Moment_H") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_heavy\">Heavy Jet Mass</h3>\n")
index.write(" <a href=\"event.html#m_heavy\">heavy jet mass,<a/>\n")
elif(val=="Moment_L") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_light\">Light Jet Mass</h3>\n")
index.write(" <a href=\"event.html#m_light\">light jet mass,<a/>\n")
elif(val=="Moment_BT") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_bt\">Total Jet Broadening</h3>\n")
index.write(" <a href=\"event.html#m_bt\">total jet broadening,<a/>\n")
elif(val=="Moment_BW") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_bw\">Wide Jet Broadening</h3>\n")
index.write(" <a href=\"event.html#m_bw\">wide jet broadening,<a/>\n")
elif(val=="Moment_BN") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_bn\">Narrow Jet Broadening</h3>\n")
index.write(" <a href=\"event.html#m_bn\">narrow jet broadening,<a/>\n")
elif(val=="Moment_C") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_C\">C-parameter</h3>\n")
index.write(" <a href=\"event.html#m_C\">C-parameter,<a/>\n")
elif(val=="Moment_S") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_S\">Sphericity</h3>\n")
index.write(" <a href=\"event.html#m_S\">sphericity,<a/>\n")
elif(val=="Moment_y") :
event.write("<div style=\"float:none; overflow:auto; width:100%\">\n<h3 id=\"m_y\">$y_{23}$</h3>\n")
index.write(" <a href=\"event.html#m_y\">$y_{23}$<a/>\n")
writePlots(analyses["EventShapes"][val],event)
event.write("</div>\n")
# footer
index.write(" </ul>\n")
event.write("</body>\n</html>")
event.close()
def writeGluon(index) :
index.write("<li> <a href=\"gluon.html\">Gluons</a>\n")
gluon=open(os.path.join(directory,"gluon.html"),'w')
gluon.write(header.format(title="Comparisions of Herwig7 and $e^+e^-$ Data on Gluon Jets"))
index.write("<ul>\n")
# charged particles dists
gluon.write("<h2 id=\"multdist\">Charged Particle Multiplicity in Gluon Jets</h2>\n")
index.write("<li> <a href=\"gluon.html#multdist\">Charged Particle Multiplicity</a> \n")
gluon.write("<div style=\"float:none; overflow:auto; width:100%\">\n")
writePlots(analyses["Charged"]["DistChargedMult"][21],gluon)
gluon.write("</div>\n")
# spectra
index.write("<li> <a href=\"gluon.html#spectra\">Charged Spectra</a> \n")
gluon.write("<h2 id=\"spectra\">Charged Particle Spectra for Gluon Jets</h2>\n")
for val in ["x","p","xi"] :
if(len(analyses["Charged"]["ChargedSpectrum"][21][val])==0) : continue
if(val=="x") :
gluon.write("<h4 id=\"spectra\">Scaled Momentum</h2>\n")
elif(val=="p") :
gluon.write("<h4 id=\"spectra\">Momentum</h2>\n")
elif(val=="xi") :
gluon.write("<h4 id=\"spectra\">Log of the Scaled Momentum</h2>\n")
gluon.write("<div style=\"float:none; overflow:auto; width:100%\">\n")
writePlots(analyses["Charged"]["ChargedSpectrum"][21][val],gluon)
gluon.write("</div>\n")
# footer
index.write("</ul>\n")
gluon.write("</body>\n</html>")
gluon.close()
# output the polarization plots
def writePolarization(index) :
pol=open(os.path.join(directory,"polarization.html"),'w')
# header for page
pol.write(header.format(title="Comparisions of Herwig7 and $e^+e^-$ Polarization Observables"))
# # line for index
index.write("<li> <a href=\"polarization.html\">Polarization Measurements</a>\n")
index.write("<ul>\n")
# pol.write("<h2 id=\"MESONS\">Mesons</h2>\n")
# Light unflavoured mesons
pol.write("<h3 id=\"m_light\">Light, Unflavoured</h3>\n")
index.write("<li><a href=\"polarization.html#m_light\">Light unflavoured mesons:<a/>\n")
writePolar(mLight,index,pol)
# Strange mesons
pol.write("<h3 id=\"m_strange\">Strange</h3>\n")
index.write("<li><a href=\"polarization.html#m_strange\">Strange mesons:<a/>\n")
writePolar(mStrange,index,pol)
# charm mesons
pol.write("<h3 id=\"m_charm\">Charm</h3>\n")
index.write("<li><a href=\"polarization.html#m_charm\">Charm mesons:<a/>\n")
writePolar(mCharm,index,pol)
# charm mesons
pol.write("<h3 id=\"m_charm\">Bottom</h3>\n")
index.write("<li><a href=\"polarization.html#m_charm\">Bottom mesons:<a/>\n")
writePolar(mBottom,index,pol)
# # charmonium
# pol.write("<h3 id=\"m_charm\">Charmonium</h3>\n")
# index.write("<li><a href=\"polarization.html#m_charm\">Charmonium:<a/>\n")
# writePolar(mccbar,index,pol)
# Baryons
pol.write("<h2 id=\"BARYONS\">Baryons</h2>\n")
# # light baryons
# pol.write("<h3 id=\"b_light\">Light, Unflavoured</h3>\n")
# index.write("<li><a href=\"polarization.html#b_light\">Light unflavoured baryons:<a/>\n")
# writePolar(bLight,index,pol)
# hyperons
pol.write("<h3 id=\"b_strange\">Hyperons</h3>\n")
index.write("<li><a href=\"polarization.html#b_strange\">Hyperons:<a/>\n")
writePolar(bStrange,index,pol)
# # charm baryons
# pol.write("<h3 id=\"b_charm\">Charm Baryons</h3>\n")
# index.write("<li><a href=\"polarization.html#b_charm\">Charm baryons:<a/>\n")
# writePolar(bCharm,index,pol)
# bottom baryons
pol.write("<h3 id=\"b_bottom\">Bottom Baryons</h3>\n")
index.write("<li><a href=\"polarization.html#b_bottom\">Bottom baryons:<a/>\n")
# loop over particles
writePolar(bBottom,index,pol)
# footer
index.write(" </ul>\n")
pol.write("</body>\n</html>")
pol.close()
print ('Total no of figures',len(figures))
index=open(os.path.join(directory,"herwig.html"),'w')
index.write(header.format(title="Comparisions of Herwig7 and $e^+e^-$ Data"))
# event shapes
writeEventShapes(index)
# charged particles
writeCharged(index)
# jets
writeJets(index)
# identified particle spectra
writeIdentified(index)
# identified particle multiplicity
writeMult(index)
# flavour
writeFlavour(index)
# gluons
writeGluon(index)
# polarization
writePolarization(index)
# QED
writeQED(index)
# tau decays
writeTauDecays(index)
+# W decays
+writeWDecays(index)
# hadron decays
writeDecays(index)
# remaining plots
if(len(figures)>0) :
writeMisc(index)
else :
print ('All figures used')
# footer
index.write("</ul>\n")
index.write("</body>\n</html>")
index.close()
diff --git a/Tests/python/rivet_check.in b/Tests/python/rivet_check.in
--- a/Tests/python/rivet_check.in
+++ b/Tests/python/rivet_check.in
@@ -1,137 +1,146 @@
#! @PYTHON@
+# -*- mode: python -*-
from __future__ import print_function
import glob,subprocess,os,optparse
op = optparse.OptionParser(usage=__doc__)
op.add_option("--obsolete", dest="obsolete" , default=False, action="store_true" , help="Warn if obsolete analyses not included")
op.add_option("--search", dest="search" , default=False, action="store_true" , help="Warn if search analyses not included")
op.add_option("--heavy-ion", dest="heavy_ion" , default=False, action="store_true" , help="Warn if heavy ion analyses not included")
op.add_option("--MC", dest="MC" , default=False, action="store_true" , help="Warn if MC analyses not included")
op.add_option("--print-descriptions", dest="output" , default=False, action="store_true" , help="Print analysis descriptions")
opts, args = op.parse_args()
# analyses to skip
skip = [ "ATLAS_2010_I849050", # alias
"TOTEM_2012_002" , # alias
"TEST" , # test analysis
"ATLAS_2015_I1351916", # same as _EL version
"ATLAS_2015_CONF_2015_041", # superseeded
"ALICE_2012_I1127497", # lead-lead
"ALICE_2012_I930312", # lead-lead
"ALICE_2015_PBPBCentrality", # lead-lead
"ATLAS_PBPB_CENTRALITY", # lead-lead
"ALICE_2015_PPBCentrality", # lead-p
"ATLAS_pPb_Calib", # lead-p
"BRAHMS_2004_AUAUCentrality",# heavy ion
"STAR_2008_S7993412", # heavy ion
"STAR_BES_CALIB", # heavy ion
"DELPHI_2002_069_CONF_603", # superseeded
"CMS_2015_I1370682_PARTON", # parton-level version
]
searches=["ALEPH_2016_I1492968","ATLAS_2019_I1725190"]
p=subprocess.Popen(["rivet","--list"],stdout=subprocess.PIPE)
analyses={}
for line in p.communicate()[0].decode("UTF-8").split("\n") :
line=line.strip()
if(line=="") : continue
temp = line.split(None,1)
if(len(temp)==2) :
analyses[temp[0].strip()] = temp[1].strip()
elif(len(temp)==1) :
analyses[temp[0].strip()] = ""
else :
print (line)
quit()
# main line hw analyses at high energy
hw_analyses={}
files=[]
for idir in glob.glob("Rivet/*") :
if( "Powheg" in idir or "MCatNLO" in idir) : continue
if ( not os.path.isdir(idir) ) : continue
if ( "Templates" in idir ) : continue
for ifile in glob.glob("%s/*.in" % idir) :
fshort=ifile.split("/")[-1].replace(".in","")
files.append(fshort)
file=open(ifile)
line=file.readline()
while line:
if("RivetAnalysis:Analyses" in line and line[0]!="#") :
line=line.strip().split()
anal = line[-1].strip().split(":")[0]
if(anal not in hw_analyses) :
hw_analyses[anal] = [fshort]
else :
hw_analyses[anal].append(fshort)
line=file.readline()
# low energy herwig analysis
hw_low_energy_analyses=[]
for executable in ["LowEnergy-EE","LowEnergy-Photon"] :
p = subprocess.Popen(["./python/%s.py"%executable,"--list","--process","All"],stdout=subprocess.PIPE)
- lowEnergy = p.communicate()[0].decode("utf-8")
+ lowEnergy = p.communicate()[0]
+ if not isinstance(lowEnergy, bytes) :
+ lowEnergy = lowEnergy.encode("UTF-8")
+ else :
+ lowEnergy = lowEnergy.decode("utf-8")
hw_low_energy_analyses+=lowEnergy.strip().split()
# R analyses
p = subprocess.Popen(["./python/R.py","--list"],stdout=subprocess.PIPE)
-Rlist = p.communicate()[0].decode("utf-8")
+Rlist = p.communicate()[0]
+if not isinstance(Rlist, bytes) :
+ Rlist = Rlist.encode("UTF-8")
+else :
+ Rlist = Rlist.decode("utf-8")
hw_low_energy_analyses += Rlist.strip().split()
anatohepmc = open("anatohepmc.txt",'w')
hepmctoana = open("hepmctoana.txt",'w')
not_in_rivet=[]
for val in hw_analyses.keys() : not_in_rivet.append(val)
# check the analyses
for analysis in sorted(analyses.keys()) :
# we have it high energy
if(analysis in hw_analyses) :
anatohepmc.write("%s %s\n" % (analysis,' '.join(sorted(hw_analyses[analysis]))) )
if("[OBSOLETE]" in analyses[analysis]) :
print ("WARNING Obsolete analysis %s included : %s" % (analysis,analyses[analysis]))
if(analysis in not_in_rivet) :
not_in_rivet.remove(analysis)
# we have it low energy or R or skipping
elif (analysis in hw_low_energy_analyses or analysis in skip) :
if(analysis in not_in_rivet) :
not_in_rivet.remove(analysis)
continue
# obsolete
elif("[OBSOLETE]" in analyses[analysis]) :
if(opts.obsolete) : print ("Obsolete analysis %s not included : %s" % (analysis,analyses[analysis]))
# searches
elif("Search" in analyses[analysis] or "search" in analyses[analysis] or analysis in searches) :
if(opts.search) : print ("Search analysis %s not included : %s" % (analysis,analyses[analysis]))
# mc only
elif(analysis[0:3]=="MC_") :
if(opts.MC) : print ("MC analysis %s not included : %s" % (analysis,analyses[analysis]))
# examples
elif("EXAMPLE" in analyses[analysis]) or "EXAMPLE" in analysis:
continue
# we don't have it
else :
p=subprocess.Popen(["rivet","--show-analysis",analysis],stdout=subprocess.PIPE)
desc=p.communicate()[0].decode("UTF-8")
beams=[]
for line in desc.split("\n") :
if("Beams:" in line) :
beams=line.replace("Beams:","").split()
nHeavy = sum((part=="Pb" or part=="Au") for part in beams)
if(nHeavy == len(beams) or nHeavy+1 == len(beams)) :
if(opts.heavy_ion) : print ("Heavy Ion analysis %s not included : %s" % (analysis,analyses[analysis]))
else :
print ("MISSING ANALYSIS",analysis,analyses[analysis])
if(opts.output) : print (desc)
# output analyses missing from rivet
for val in not_in_rivet:
print ("NOT IN RIVET ",val)
# output second file for rivet
anatohepmc.close()
for fname in sorted(files) :
anals=[]
for anal in hw_analyses :
if(fname in hw_analyses[anal]) :
anals.append(anal)
hepmctoana.write("%s %s\n" % (fname,' '.join(sorted(anals))) )
hepmctoana.close()
diff --git a/UnderlyingEvent/MPIHandler.h b/UnderlyingEvent/MPIHandler.h
--- a/UnderlyingEvent/MPIHandler.h
+++ b/UnderlyingEvent/MPIHandler.h
@@ -1,898 +1,890 @@
// -*- C++ -*-
//
// MPIHandler.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_MPIHandler_H
#define HERWIG_MPIHandler_H
//
// This is the declaration of the MPIHandler class.
//
#include "ThePEG/Interface/Interfaced.h"
#include "ThePEG/Handlers/StandardEventHandler.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "Herwig/PDT/StandardMatchers.h"
#include "Herwig/Utilities/GSLBisection.h"
//#include "Herwig/Utilities/GSLMultiRoot.h"
#include "Herwig/Utilities/GSLIntegrator.h"
#include "Herwig/Shower/UEBase.h"
#include <cassert>
#include "ProcessHandler.h"
#include "MPIHandler.fh"
namespace Herwig {
using namespace ThePEG;
/** \ingroup UnderlyingEvent
* \class MPIHandler
* This class is responsible for generating additional
* semi hard partonic interactions.
*
* \author Manuel B\"ahr
*
* @see \ref MPIHandlerInterfaces "The interfaces"
* defined for MPIHandler.
* @see ProcessHandler
* @see ShowerHandler
* @see HwRemDecayer
*/
class MPIHandler: public UEBase {
/**
* Maximum number of scatters
*/
static const unsigned int maxScatters_ = 99;
/**
* Class for the integration is a friend to access private members
*/
friend struct Eikonalization;
friend struct TotalXSecBisection;
friend struct slopeAndTotalXSec;
friend struct slopeInt;
friend struct slopeBisection;
public:
/** A vector of <code>SubProcessHandler</code>s. */
typedef vector<SubHdlPtr> SubHandlerList;
/** A vector of <code>Cut</code>s. */
typedef vector<CutsPtr> CutsList;
/** A vector of <code>ProcessHandler</code>s. */
typedef vector<ProHdlPtr> ProcessHandlerList;
/** A vector of cross sections. */
typedef vector<CrossSection> XSVector;
/** A pair of multiplicities: hard, soft. */
typedef pair<unsigned int, unsigned int> MPair;
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
MPIHandler(): softMult_(0), identicalToUE_(-1),
PtOfQCDProc_(-1.0*GeV), Ptmin_(-1.0*GeV),
hardXSec_(0*millibarn), softXSec_(0*millibarn),
totalXSecExp_(0*millibarn),
softMu2_(ZERO), beta_(100.0/GeV2),
algorithm_(2), numSubProcs_(0),
colourDisrupt_(0.0), softInt_(true), twoComp_(true),
DLmode_(2), avgNhard_(0.0), avgNsoft_(0.0),
energyExtrapolation_(3), EEparamA_(0.6*GeV),
EEparamB_(37.5*GeV), refScale_(7000.*GeV),
pT0_(2.875*GeV), b_(0.3101), offset_(622.204*GeV) {}
- /**
- * The destructor.
- */
- virtual ~MPIHandler(){}
- //@}
-
public:
/** @name Methods for the MPI generation. */
//@{
/*
* @return true if for this beam setup MPI can be generated
*/
virtual bool beamOK() const;
/**
* Return true or false depending on whether soft interactions are enabled.
*/
virtual bool softInt() const {return softInt_;}
/**
* Get the soft multiplicity from the pretabulated multiplicity
* distribution. Generated in multiplicity in the first place.
* @return the number of extra soft events in this collision
*/
virtual unsigned int softMultiplicity() const {return softMult_;}
/**
* Sample from the pretabulated multiplicity distribution.
* @return the number of extra events in this collision
*/
virtual unsigned int multiplicity(unsigned int sel=0);
/**
* Select a StandardXComb according to it's weight
* @return that StandardXComb Object
* @param sel is the subprocess that should be returned,
* if more than one is specified.
*/
virtual tStdXCombPtr generate(unsigned int sel=0);
//@}
/** @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();
/**
* Initialize this Multiple Interaction handler and all related objects needed to
* generate additional events.
*/
virtual void initialize();
/**
* Finalize this Multiple Interaction handler and all related objects needed to
* generate additional events.
*/
virtual void finalize();
/**
* Clean up the XCombs from our subprocesses after each event.
* ThePEG cannot see them, so the usual cleaning misses these.
*/
virtual void clean();
/**
* Write out accumulated statistics about integrated cross sections.
*/
void statistics() const;
/**
* The level of statistics. Controlls the amount of statistics
* written out after each run to the <code>EventGenerator</code>s
* <code>.out</code> file. Simply the EventHandler method is called here.
*/
int statLevel() const {return eventHandler()->statLevel();}
/**
* Return the hard cross section above ptmin
*/
CrossSection hardXSec() const { return hardXSec_; }
/**
* Return the soft cross section below ptmin
*/
CrossSection softXSec() const { return softXSec_; }
/**
* Return the inelastic cross section
*/
CrossSection inelasticXSec() const { return inelXSec_; }
/**
* Return the non-diffractive cross section assumed by the model.
* TODO: See comment at diffractiveXSec.
*/
CrossSection nonDiffractiveXSec() const {
return (1.-diffratio_)*inelXSec_;
}
/**
* Return the diffractive cross section assumed by the model.
* For now the diffractive cross section is seen as a fixed part of the
* inelastic cross section.
* TODO: Energy dependence and/or Include diffraction in Eikonalisation.
*/
CrossSection diffractiveXSec() const {
return diffratio_*inelXSec_;
}
/** @name Simple access functions. */
//@{
/**
* Return the ThePEG::EventHandler assigned to this handler.
* This methods shadows ThePEG::StepHandler::eventHandler(), because
* it is not virtual in ThePEG::StepHandler. This is ok, because this
* method would give a null-pointer at some stages, whereas this method
* gives access to the explicitely copied pointer (in initialize())
* to the ThePEG::EventHandler.
*/
tEHPtr eventHandler() const {return theHandler;}
/**
* Return the current handler
*/
static const MPIHandler * currentHandler() {
return currentHandler_;
}
/**
* Return theAlgorithm.
*/
virtual int Algorithm() const {return algorithm_;}
/**
* Return the ptmin parameter of the model
*/
virtual Energy Ptmin() const {
if(Ptmin_ > ZERO)
return Ptmin_;
else
throw Exception() << "MPIHandler::Ptmin called without initialize before"
<< Exception::runerror;
}
/**
* Return the slope of the soft pt spectrum as calculated.
*/
virtual InvEnergy2 beta() const {
if(beta_ != 100.0/GeV2)
return beta_;
else
throw Exception() << "MPIHandler::beta called without initialization"
<< Exception::runerror;
}
/**
* Return the pt Cutoff of the Interaction that is identical to the UE
* one.
*/
virtual Energy PtForVeto() const {return PtOfQCDProc_;}
/**
* Return the number of additional "hard" processes ( = multiple
* parton scattering)
*/
virtual unsigned int additionalHardProcs() const {return numSubProcs_-1;}
/**
* Return the fraction of colour disrupted connections to the
* suprocesses.
*/
virtual double colourDisrupt() const {return colourDisrupt_;}
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
private:
/**
* Access the list of sub-process handlers.
*/
const SubHandlerList & subProcesses()
const {return theSubProcesses;}
/**
* Access the list of sub-process handlers.
*/
SubHandlerList & subProcesses() {return theSubProcesses;}
/**
* Access the list of cuts.
*/
const CutsList & cuts() const {return theCuts;}
/**
* Access the list of cuts.
*/
CutsList & cuts() {return theCuts;}
/**
* Access the list of sub-process handlers.
*/
const ProcessHandlerList & processHandlers()
const {return theProcessHandlers;}
/**
* Access the list of sub-process handlers.
*/
ProcessHandlerList & processHandlers() {return theProcessHandlers;}
/**
* Method to calculate the individual probabilities for N scatters in the event.
* @param UEXSecs is(are) the inclusiv cross section(s) for the UE process(es).
*/
void Probs(XSVector UEXSecs);
/**
* Debug method to check the individual probabilities.
* @param filename is the file the output gets written to
*/
void MultDistribution(string filename) const;
/**
* Return the value of the Overlap function A(b) for a given impact
* parameter \a b.
* @param b impact parameter
* @param mu2 = inv hadron radius squared. 0 will use the value of
* invRadius_
* @return inverse area.
*/
InvArea OverlapFunction(Length b, Energy2 mu2=ZERO) const;
/**
* Method to calculate the poisson probability for expectation value
* \f$<n> = A(b)\sigma\f$, and multiplicity N.
*/
double poisson(Length b, CrossSection sigma,
unsigned int N, Energy2 mu2=ZERO) const;
/**
* Returns the total cross section for the current CMenergy. The
* decision which parametrization will be used is steered by a
* external parameter of this class.
*/
CrossSection totalXSecExp() const;
/**
* Difference of the calculated total cross section and the
* experimental one from totalXSecExp.
* @param softXSec = the soft cross section that is used
* @param softMu2 = the soft radius, if 0 the hard radius will be used
*/
CrossSection totalXSecDiff(CrossSection softXSec,
Energy2 softMu2=ZERO) const;
/**
* Difference of the calculated elastic slope and the
* experimental one from slopeExp.
* @param softXSec = the soft cross section that is used
* @param softMu2 = the soft radius, if 0 the hard radius will be used
*/
InvEnergy2 slopeDiff(CrossSection softXSec,
Energy2 softMu2=ZERO) const;
/**
* Returns the value of the elastic slope for the current CMenergy.
* The decision which parametrization will be used is steered by a
* external parameter of this class.
*/
InvEnergy2 slopeExp() const;
/**
* Calculate the minimal transverse momentum from the extrapolation
*/
void overrideUECuts();
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MPIHandler & operator=(const MPIHandler &) = delete;
/**
* A pointer to the EventHandler that calls us. Has to be saved, because the
* method eventHandler() inherited from ThePEG::StepHandler returns a null-pointer
* sometimes. Leif changed that in r1053 so that a valid pointer is present, when
* calling doinitrun().
*/
tEHPtr theHandler;
/**
* The list of <code>SubProcessHandler</code>s.
*/
SubHandlerList theSubProcesses;
/**
* The kinematical cuts used for this collision handler.
*/
CutsList theCuts;
/**
* List of ProcessHandler used to sample different processes independently
*/
ProcessHandlerList theProcessHandlers;
/**
* A ThePEG::Selector where the individual Probabilities P_N are stored
* and the actual Multiplicities can be selected.
*/
Selector<MPair> theMultiplicities;
/**
* Variable to store the soft multiplicity generated for a event. This
* has to be stored as it is generated at the time of the hard
* additional interactions but used later on.
*/
unsigned int softMult_;
/**
* Variable to store the multiplicity of the second hard process
*/
vector<int> additionalMultiplicities_;
/**
* Variable to store the information, which process is identical to
* the UE one (QCD dijets).
* 0 means "real" hard one
* n>0 means the nth additional hard scatter
* -1 means no one!
*/
int identicalToUE_;
/**
* Variable to store the minimal pt of the process that is identical
* to the UE one. This only has to be set, if it can't be determined
* automatically (i.e. when reading QCD LesHouches files in).
*/
Energy PtOfQCDProc_;
/**
* Variable to store the parameter ptmin
*/
Energy Ptmin_;
/**
* Variable to store the hard cross section above ptmin
*/
CrossSection hardXSec_;
/**
* Variable to store the final soft cross section below ptmin
*/
CrossSection softXSec_;
/**
* Variable to store the inelastic cross section
*/
CrossSection inelXSec_;
/**
* Variable to store the total pp cross section (assuming rho=0!) as
* measured at LHC. If this variable is set, this value is used in the
* subsequent run instead of any of the Donnachie-Landshoff
* parametrizations.
*/
CrossSection totalXSecExp_;
/**
* Variable to store the soft radius, that is calculated during
* initialization for the two-component model.
*/
Energy2 softMu2_;
/**
* slope to the non-perturbative pt spectrum: \f$d\sigma/dp_T^2 = A \exp
* (- beta p_T^2)\f$. Its value is determined durint initialization.
*/
InvEnergy2 beta_;
/**
* Switch to be set from outside to determine the algorithm used for
* UE activity.
*/
int algorithm_;
/**
* Inverse hadron Radius squared \f$ (\mu^2) \f$. Used inside the overlap function.
*/
Energy2 invRadius_;
/**
* Member variable to store the actual number of separate SubProcesses
*/
unsigned int numSubProcs_;
/**
* Variable to store the relative number of colour disrupted
* connections to additional subprocesses. This variable is used in
* Herwig::HwRemDecayer but store here, to have access to all
* parameters through one Object.
*/
double colourDisrupt_;
/**
* Flag to store whether soft interactions, i.e. pt < ptmin should be
* simulated.
*/
bool softInt_;
/**
* Flag to steer wheather the soft part has a different radius, that
* will be dynamically fixed.
*/
bool twoComp_;
/**
* Switch to determine which Donnachie & Landshoff parametrization
* should be used.
*/
unsigned int DLmode_;
/**
* Variable to store the average hard multiplicity.
*/
double avgNhard_;
/**
* Variable to store the average soft multiplicity.
*/
double avgNsoft_;
/**
* The current handler
*/
static MPIHandler * currentHandler_;
/**
* Flag to store whether to calculate the minimal UE pt according to an
* extrapolation formula or whether to use MPIHandler:Cuts[0]:OneCuts[0]:MinKT
*/
unsigned int energyExtrapolation_;
/**
* Parameters for the energy extrapolation formula
*/
Energy EEparamA_;
Energy EEparamB_;
Energy refScale_;
Energy pT0_;
double b_;
Energy offset_;
/**
* Parameters to set the fraction of diffractive cross section in the inelastic cross section.
*/
double diffratio_=0.2;
protected:
/** @cond EXCEPTIONCLASSES */
/**
* Exception class used by the MultipleInteractionHandler, when something
* during initialization went wrong.
* \todo understand!!!
*/
class InitError: public Exception {};
/** @endcond */
};
}
namespace Herwig {
/**
* A struct for the 2D root finding that is necessary to determine the
* soft cross section and the soft radius that is needed to describe
* the total cross section correctly.
* NOT IN USE CURRENTLY
*/
struct slopeAndTotalXSec : public GSLHelper<CrossSection, CrossSection> {
public:
/**
* Constructor
*/
slopeAndTotalXSec(tcMPIHPtr handler): handler_(handler) {}
/** second argument type */
typedef Energy2 ArgType2;
/** second value type */
typedef InvEnergy2 ValType2;
/** first element of the vector like function to find root for
* @param softXSec soft cross-section
* @param softMu2 \f$\mu^2\f$
*/
CrossSection f1(ArgType softXSec, ArgType2 softMu2) const {
return handler_->totalXSecDiff(softXSec, softMu2);
}
/** second element of the vector like function to find root for
* @param softXSec soft cross-section
* @param softMu2 \f$\mu^2\f$
*/
InvEnergy2 f2(ArgType softXSec, ArgType2 softMu2) const {
return handler_->slopeDiff(softXSec, softMu2);
}
/** provide the actual units of use */
virtual ValType vUnit() const {return 1.0*millibarn;}
/** otherwise rounding errors may get significant */
virtual ArgType aUnit() const {return 1.0*millibarn;}
/** provide the actual units of use */
ValType2 vUnit2() const {return 1.0/GeV2;}
/** otherwise rounding errors may get significant */
ArgType2 aUnit2() const {return GeV2;}
private:
/**
* Pointer to the handler
*/
tcMPIHPtr handler_;
};
/**
* A struct for the root finding that is necessary to determine the
* slope of the soft pt spectrum to match the soft cross section
*/
struct betaBisection : public GSLHelper<Energy2, InvEnergy2>{
public:
/**
* Constructor.
* @param soft = soft cross section, i.e. the integral of the soft
* pt spectrum f(u=p_T^2) = dsig exp(-beta*u/u_min)
* @param dsig = dsigma_hard/dp_T^2 at the p_T cutoff
* @param ptmin = p_T cutoff
*/
betaBisection(CrossSection soft, DiffXSec dsig, Energy ptmin)
: softXSec_(soft), dsig_(dsig), ptmin_(ptmin) {}
/**
* Operator that is used inside the GSLBisection class
*/
virtual Energy2 operator ()(InvEnergy2 beta) const
{
if( fabs(beta*GeV2) < 1.E-4 )
beta = (beta > ZERO) ? 1.E-4/GeV2 : -1.E-4/GeV2;
return (exp(beta*sqr(ptmin_)) - 1.0)/beta - softXSec_/dsig_;
}
/** provide the actual units of use */
virtual ValType vUnit() const {return 1.0*GeV2;}
/** provide the actual units of use */
virtual ArgType aUnit() const {return 1.0/GeV2;}
private:
/** soft cross section */
CrossSection softXSec_;
/** dsigma/dp_T^2 at ptmin */
DiffXSec dsig_;
/** pt cutoff */
Energy ptmin_;
};
/**
* A struct for the root finding that is necessary to determine the
* soft cross section and soft mu2 that are needed to describe the
* total cross section AND elastic slope correctly.
*/
struct slopeBisection : public GSLHelper<InvEnergy2, Energy2> {
public:
/** Constructor */
slopeBisection(tcMPIHPtr handler) : handler_(handler) {}
/**
* Return the difference of the calculated elastic slope to the
* experimental one for a given value of the soft mu2. During that,
* the soft cross section get fixed.
*/
InvEnergy2 operator ()(Energy2 arg) const;
/** Return the soft cross section that has been calculated */
CrossSection softXSec() const {return softXSec_;}
private:
/** const pointer to the MPIHandler to give access to member functions.*/
tcMPIHPtr handler_;
/** soft cross section that is determined on the fly.*/
mutable CrossSection softXSec_;
};
/**
* A struct for the root finding that is necessary to determine the
* soft cross section that is needed to describe the total cross
* section correctly.
*/
struct TotalXSecBisection : public GSLHelper<CrossSection, CrossSection> {
public:
/**
* Constructor
* @param handler The handler
* @param softMu2 \f$\mu^2\f$
*/
TotalXSecBisection(tcMPIHPtr handler, Energy2 softMu2=ZERO):
handler_(handler), softMu2_(softMu2) {}
/**
* operator to return the cross section
* @param argument input cross section
*/
CrossSection operator ()(CrossSection argument) const {
return handler_->totalXSecDiff(argument, softMu2_);
}
/** provide the actual units of use */
virtual ValType vUnit() const {return 1.0*millibarn;}
/** otherwise rounding errors may get significant */
virtual ArgType aUnit() const {return 1.0*millibarn;}
private:
/**
* The handler
*/
tcMPIHPtr handler_;
/**
* \f$\mu^2\f$
*/
Energy2 softMu2_;
};
/**
* Typedef for derivative of the length
*/
typedef decltype(mm/GeV2) LengthDiff;
/**
* A struct for the integrand for the slope
*/
struct slopeInt : public GSLHelper<LengthDiff, Length>{
public:
/** Constructor
* @param handler The handler
* @param hard The hard cross section
* @param soft The soft cross section
* @param softMu2 \f$\mu^2\f$
*/
slopeInt(tcMPIHPtr handler, CrossSection hard,
CrossSection soft=0*millibarn, Energy2 softMu2=ZERO)
: handler_(handler), hardXSec_(hard),
softXSec_(soft), softMu2_(softMu2) {}
/**
* Operator to return the answer
* @param arg The argument
*/
ValType operator ()(ArgType arg) const;
private:
/**
* Pointer to the Handler that calls this integrand
*/
tcMPIHPtr handler_;
/**
* The hard cross section to be eikonalized
*/
CrossSection hardXSec_;
/**
* The soft cross section to be eikonalized. Default is zero
*/
CrossSection softXSec_;
/**
* The inv radius^2 of the soft interactions.
*/
Energy2 softMu2_;
};
/**
* A struct for the eikonalization of the inclusive cross section.
*/
struct Eikonalization : public GSLHelper<Length, Length>{
/**
* The constructor
* @param handler is the pointer to the MPIHandler to get access to
* MPIHandler::OverlapFunction and member variables of the MPIHandler.
* @param option is a flag, whether the inelastic or the total
* @param handler The handler
* @param hard The hard cross section
* @param soft The soft cross section
* @param softMu2 \f$\mu^2\f$
* cross section should be returned (-2 or -1). For option = N > 0 the integrand
* is N*(A(b)*sigma)^N/N! exp(-A(b)*sigma) this is the P_N*sigma where
* P_N is the Probability of having exactly N interaction (including the hard one)
* This is equation 14 from "Jimmy4: Multiparton Interactions in HERWIG for the LHC"
*/
Eikonalization(tcMPIHPtr handler, int option, CrossSection hard,
CrossSection soft=0*millibarn, Energy2 softMu2=ZERO)
: theHandler(handler), theoption(option), hardXSec_(hard),
softXSec_(soft), softMu2_(softMu2) {}
/**
* Get the function value
*/
Length operator ()(Length argument) const;
private:
/**
* Pointer to the Handler that calls this integrand
*/
tcMPIHPtr theHandler;
/**
* A flag to switch between the calculation of total and inelastic cross section
* or calculations for the individual probabilities. See the constructor
*/
int theoption;
/**
* The hard cross section to be eikonalized
*/
CrossSection hardXSec_;
/**
* The soft cross section to be eikonalized. Default is zero
*/
CrossSection softXSec_;
/**
* The inv radius^2 of the soft interactions.
*/
Energy2 softMu2_;
};
}
#endif /* HERWIG_MPIHandler_H */
diff --git a/UnderlyingEvent/ProcessHandler.cc b/UnderlyingEvent/ProcessHandler.cc
--- a/UnderlyingEvent/ProcessHandler.cc
+++ b/UnderlyingEvent/ProcessHandler.cc
@@ -1,443 +1,432 @@
// -*- C++ -*-
//
// ProcessHandler.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 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 ProcessHandler class.
//
#include "ProcessHandler.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "MPISampler.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/Handlers/SubProcessHandler.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/Utilities/SimplePhaseSpace.h"
#include "ThePEG/PDF/PartonExtractor.h"
#include "ThePEG/MatrixElement/MEBase.h"
#include "ThePEG/Handlers/LuminosityFunction.h"
#include "ThePEG/Handlers/CascadeHandler.h"
#include "ThePEG/Cuts/Cuts.h"
#include "Herwig/Utilities/GaussianIntegrator.h"
#include "gsl/gsl_sf_bessel.h"
#ifdef ThePEG_TEMPLATES_IN_CC_FILE
// #include "ProcessHandler.tcc"
#endif
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
ProcessHandler::ProcessHandler()
: theBinStrategy(2) {}
-ProcessHandler::ProcessHandler(const ProcessHandler & x)
- : Interfaced(x), LastXCombInfo<>(x),
- theSampler(x.theSampler), theHandler(x.theHandler),
- theCuts(x.theCuts), theSubProcess(x.theSubProcess),
- theXCombs(x.theXCombs), theXSecs(x.theXSecs),
- theBinStrategy(x.theBinStrategy), theMEXMap(x.theMEXMap),
- theMaxDims(x.theMaxDims) {}
-
-
-ProcessHandler::~ProcessHandler() {}
-
void ProcessHandler::initialize(tSubHdlPtr sub, tCutsPtr cut, tEHPtr eh) {
/*
This method should be called during the "read" phase! However due to
the unpredictable order in which objects are set up by ThePEG it is not
guaranteed that the EventHandler is present. So we move that to
doinitrun of the MPIHandler!
*/
if( !eh || !sub || !cut )
throw Exception() << "ProcessHandler was created without specifying a SubProcess "
<< "or a Cut Object or the EventHandler."
<< Exception::runerror;
theHandler = eh;
theCuts = cut;
theSubProcess = sub;
theSampler = new_ptr(MPISampler());
Energy maxEnergy = lumiFn().maximumCMEnergy();
xCombs().clear();
xSecs().clear();
cuts()->initialize(sqr(maxEnergy), lumiFn().Y());
CutsPtr kincuts = (*subProcess()).cuts()? (*subProcess()).cuts(): cuts();
if ( (*subProcess()).cuts() ) kincuts->initialize(sqr(maxEnergy), lumiFn().Y());
PExtrPtr pextract = (*subProcess()).pExtractor();
// Use an empty ckkw handler for the additional interactions:
tCascHdlPtr ckkw = tCascHdlPtr();
PartonPairVec vpc = pextract->getPartons(maxEnergy, incoming(), *kincuts);
// The last parton bin pair was in fact the bins corresponding to
// the incoming particles, so we remove them, but save them to
// keep them referenced.
PBPair orig = vpc.back();
vpc.pop_back();
for ( PartonPairVec::iterator ppit = vpc.begin();
ppit != vpc.end(); ++ppit )
for ( MEVector::const_iterator meit = (*subProcess()).MEs().begin();
meit != (*subProcess()).MEs().end(); ++meit )
addME(maxEnergy, subProcess(), pextract, kincuts, ckkw, *meit, *ppit);
xSecs().resize(xCombs().size());
theMaxDims.clear();
switch ( binStrategy() ) {
case 0: {
theMaxDims.push_back(0);
for ( int i = 0, N = xCombs().size(); i < N; ++i )
theMaxDims[0] = max(theMaxDims[0], xCombs()[i]->nDim());
break;
}
case 1: {
for ( int i = 0, N = xCombs().size(); i < N; ++i )
theMEXMap[xCombs()[i]->matrixElement()].push_back(xCombs()[i]);
MEXMap::const_iterator mei = theMEXMap.begin();
for ( int i = 0, N = theMEXMap.size(); i < N; ++i, ++mei) {
theMaxDims.push_back(0);
for ( int j = 0, M = mei->second.size(); j < M; ++j )
theMaxDims[i] = max(theMaxDims[i], mei->second[j]->nDim());
}
break;
}
case 2: {
for ( int i = 0, N = xCombs().size(); i < N; ++i )
theMaxDims.push_back(xCombs()[i]->nDim());
break;
}
}
tMPISamplerPtr smplr = dynamic_ptr_cast<tMPISamplerPtr>(sampler());
smplr->setProcessHandler(this);
//sample 2 PSpoints to check for zero xsec in advance
smplr->initialize();
}
void ProcessHandler::
addME(Energy maxEnergy, tSubHdlPtr sub, tPExtrPtr extractor, tCutsPtr cuts,
tCascHdlPtr ckkw, tMEPtr me, const PBPair & pBins) {
typedef MEBase::DiagramVector DiagramVector;
typedef map<string,DiagramVector> DiagramMap;
cPDPair pin(pBins.first->parton(), pBins.second->parton());
DiagramVector diag = me->diagrams();
DiagramMap tdiag;
DiagramMap tmdiag;
for ( int i = 0, N = diag.size(); i < N; ++i ) {
if ( diag[i]->partons()[0] == pin.first &&
diag[i]->partons()[1] == pin.second )
tdiag[diag[i]->getTag()].push_back(diag[i]);
if ( diag[i]->partons()[0] == pin.second &&
diag[i]->partons()[1] == pin.first )
tmdiag[diag[i]->getTag()].push_back(diag[i]);
}
bool mirror = false;
if ( ( mirror = tdiag.empty() ) ) tdiag = tmdiag;
for ( DiagramMap::iterator dit = tdiag.begin(); dit != tdiag.end(); ++dit ) {
//todo: hope that it is no problem that I take the EventHandler here and not the ProcessHandler:
StdXCombPtr xcomb =
new_ptr(StandardXComb(maxEnergy, incoming(), eventHandler(),
sub, extractor, ckkw, pBins, cuts, me, dit->second, mirror));
if ( xcomb->checkInit() ) xCombs().push_back(xcomb);
else generator()->logWarning(
InitError() << "The matrix element '"
<< xcomb->matrixElement()->name() << "' cannot generate the diagram '"
<< dit->first << "' when used together with the parton extractor '"
<< xcomb->pExtractor()->name()
<< "'. The corresponding diagram is switched off." << Exception::warning);
}
}
tStdXCombPtr ProcessHandler::select(int bin, double weight) {
int i = upper_bound(xSecs().begin(), xSecs().end(), UseRandom::rnd()*xSecs().back())
- xSecs().begin();
tStdXCombPtr lastXC;
switch ( binStrategy() ) {
case 0:
lastXC = xCombs()[i];
break;
case 1: {
MEXMap::iterator mei = theMEXMap.begin();
for ( int j = 0; j < bin; ++j) ++mei;
lastXC = mei->second[i];
break;
}
case 2:
lastXC = xCombs()[bin];
break;
}
// clean up the old XComb object before switching to a new one
if ( theLastXComb && theLastXComb != lastXC ) theLastXComb->clean();
theLastXComb = lastXC;
lastXC->select(weight);
lastXC->accept();
lastXC->matrixElement()->setXComb(lastXC);
return lastXC;
}
CrossSection ProcessHandler::
dSigDR(const pair<double,double> ll, Energy2 maxS,
int ibin, int nr, const double * r) {
PPair inc = make_pair(incoming().first->produceParticle(),
incoming().second->produceParticle());
SimplePhaseSpace::CMS(inc, maxS);
XVector xv;
switch ( binStrategy() ) {
case 0:
xv = xCombs();
break;
case 1: {
MEXMap::iterator mei = theMEXMap.begin();
for ( int i = 0; i < ibin; ++i) ++mei;
xv = mei->second;
break;
}
case 2:
xv = XVector(1, xCombs()[ibin]);
break;
}
xSecs().resize(xv.size());
for ( int i = 0, N = xv.size(); i < N; ++i ) xv[i]->prepare(inc);
CrossSection sum = 0.0*nanobarn;
for ( int i = 0, N = xv.size(); i < N; ++i )
xSecs()[i] = ( sum += xv[i]->dSigDR(ll, nr, r) );
return sum;
}
CrossSection ProcessHandler::dSigDR(const vector<double> & r) {
double jac = 1.0;
pair<double,double> ll = lumiFn().generateLL(&r[0], jac);
Energy2 maxS = sqr(lumiFn().maximumCMEnergy())/exp(ll.first + ll.second);
int bin = sampler()->lastBin();
CrossSection x = jac*lumiFn().value(incoming(), ll.first, ll.second)
*dSigDR(ll, maxS, bin, nDim(bin) - lumiDim(), &r[lumiDim()]);
return x;
}
int ProcessHandler::nBins() const {
switch ( binStrategy() ) {
case 0: return 1;
case 1: return theMEXMap.size();
case 2: return xCombs().size();
}
return -1;
}
void ProcessHandler::doinitrun() {
Interfaced::doinitrun();
sampler()->initrun();
for ( int i = 0, N = xCombs().size(); i < N; ++i )
xCombs()[i]->reset();
double weight(0);
//sample N PSpoints to get an estimate of the xsec
for(unsigned int i=0; i<100000; i++){
weight = sampler()->generate();
tStdXCombPtr lastXC = select(sampler()->lastBin(), weight);
}
}
CrossSection ProcessHandler::integratedXSec() const {
if ( sampler()->integratedXSec() == 0.0*nanobarn )
return sampler()->maxXSec();
Stat tot;
for ( int i = 0, N = xCombs().size(); i < N; ++i ) {
const StandardXComb & x = *xCombs()[i];
Stat s;
s = Stat(x.stats().attempts(), x.stats().accepted(),
x.stats().sumWeights(), sampler()->integratedXSec(),
sampler()->sumWeights());
tot += s;
}
return tot.xSec();
}
void ProcessHandler::statistics(ostream & os, Stat & tot) const {
if ( statLevel() == 0 ) return;
map<cPDPair, Stat> partonMap;
map<MEPtr, Stat> meMap;
map<PExtrPtr, Stat> extractMap;
// Stat tot;
for ( int i = 0, N = xCombs().size(); i < N; ++i ) {
const StandardXComb & x = *xCombs()[i];
Stat s;
s = Stat(x.stats().attempts(), x.stats().accepted(),
x.stats().sumWeights(), sampler()->integratedXSec(),
sampler()->sumWeights());
partonMap[x.partons()] += s;
meMap[x.matrixElement()] += s;
extractMap[x.pExtractor()] += s;
tot += s;
}
string line = "======================================="
"=======================================\n";
if ( tot.accepted <= 0 ) {
os << line << "No events generated by event handler '" << name() << "'."
<< endl;
return;
}
os //<< line << "Statistics for event handler \'" << name() << "\':\n"
<< " "
<< "generated number of Cross-section\n"
<< " "
<< " events attempts (nb)\n";
os << line << "Total:" << setw(42) << tot.accepted << setw(13)
<< tot.attempted << setw(17) << tot.xSec()/nanobarn << endl
<< line;
if ( statLevel() == 1 ) return;
os << "Per matrix element breakdown:\n";
for ( map<MEPtr, Stat>::iterator i = meMap.begin();
i != meMap.end(); ++i ) {
string n = i->first->name();
n.resize(37, ' ');
os << n << setw(11) << i->second.accepted << setw(13)
<< i->second.attempted << setw(17) << i->second.xSec()/nanobarn << endl;
}
os << line;
if ( statLevel() == 2 ) return;
os << "Per parton extractor breakdown:\n";
for ( map<PExtrPtr, Stat>::iterator i = extractMap.begin();
i != extractMap.end(); ++i ) {
string n = i->first->name();
n.resize(37, ' ');
os << n << setw(11) << i->second.accepted << setw(13)
<< i->second.attempted << setw(17) << i->second.xSec()/millibarn << endl;
}
os << line;
os << "Per incoming partons breakdown:\n";
for ( map<cPDPair, Stat>::iterator i = partonMap.begin();
i != partonMap.end(); ++i ) {
string n = i->first.first->PDGName() + " " + i->first.second->PDGName();
n.resize(37, ' ');
os << n << setw(11) << i->second.accepted << setw(13)
<< i->second.attempted << setw(17) << i->second.xSec()/millibarn << endl;
}
os << line;
if ( statLevel() == 3 ) return;
os << "Detailed breakdown:\n";
double xsectot = sampler()->integratedXSec()/
(sampler()->sumWeights()*nanobarn);
for ( int i = 0, N = xCombs().size(); i < N; ++i ) {
const StandardXComb & x = *xCombs()[i];
os << "(" << x.pExtractor()->name() << ") "
<< x.partons().first->PDGName() << " "
<< x.partons().second->PDGName()
<< " (" << x.matrixElement()->name() << " "
<< x.lastDiagram()->getTag() << ") " << endl
<< setw(48) << x.stats().accepted() << setw(13) << x.stats().attempts()
<< setw(17) << x.stats().sumWeights()*xsectot << endl;
}
os << line;
}
void ProcessHandler::persistentOutput(PersistentOStream & os) const {
os << theBinStrategy << theSubProcess << theCuts << theLastXComb
<< theXCombs << ounit(theXSecs, nanobarn)
<< theMaxDims << theMEXMap
<< theSampler << theHandler;
}
void ProcessHandler::persistentInput(PersistentIStream & is, int) {
is >> theBinStrategy >> theSubProcess >> theCuts >> theLastXComb
>> theXCombs >> iunit(theXSecs, nanobarn)
>> theMaxDims >> theMEXMap
>> theSampler >> theHandler;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<ProcessHandler,Interfaced>
describeHerwigProcessHandler("Herwig::ProcessHandler", "JetCuts.so SimpleKTCut.so HwMPI.so");
void ProcessHandler::Init() {
static ClassDocumentation<ProcessHandler> documentation
("There is soon documentation for the ProcessHandler class");
/*
* Object will be created outside of *.in files
*
static Switch<ProcessHandler,int> interfaceBinStrategy
("BinStrategy",
"The strategy to be used when sampling different ThePEG::XComb "
"objects. An ThePEG::XComb objet represents a pair of incoming "
"parton types as defined by a ThePEG::PartonExtractor and a "
"matrix element.",
&ProcessHandler::theBinStrategy, 2, false, false);
static SwitchOption interfaceBinStrategy0
(interfaceBinStrategy,
"AllAtOnce",
"All bins are sampled together.",
0);
static SwitchOption interfaceBinStrategy1
(interfaceBinStrategy,
"PerME",
"All bins which have the same matrix element object are sampled together.",
1);
static SwitchOption interfaceBinStrategy2
(interfaceBinStrategy,
"Individual",
"All bins are sampled individually.",
2);
*/
}
diff --git a/UnderlyingEvent/ProcessHandler.h b/UnderlyingEvent/ProcessHandler.h
--- a/UnderlyingEvent/ProcessHandler.h
+++ b/UnderlyingEvent/ProcessHandler.h
@@ -1,422 +1,409 @@
// -*- C++ -*-
//
// ProcessHandler.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2019 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_ProcessHandler_H
#define HERWIG_ProcessHandler_H
//
// This is the declaration of the ProcessHandler class.
//
#include "ThePEG/Interface/Interfaced.h"
#include "ThePEG/Handlers/StandardEventHandler.h"
#include "ThePEG/Handlers/StandardXComb.h"
#include "ThePEG/Handlers/SubProcessHandler.h"
#include "ThePEG/Handlers/LuminosityFunction.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Handlers/SamplerBase.h"
#include "ThePEG/Cuts/Cuts.h"
#include "ThePEG/MatrixElement/MEBase.h"
#include "ThePEG/Handlers/CascadeHandler.h"
#include <cassert>
#include "ProcessHandler.fh"
#include "stat.h"
namespace Herwig {
using namespace ThePEG;
/** \ingroup UnderlyingEvent
* \class ProcessHandler
* This class is for handling the sampling of
* semi hard partonic interactions. If several types of partonic interactions
* are needed. Each of them has it's own ProcessHandler. A reference to them is
* stored in MPIHandler, which administers everything.
*
* \author Manuel B\"ahr
*
* @see \ref ProcessHandlerInterfaces "The interfaces"
* defined for ProcessHandler.
* @see MPISampler
* @see MPIHandler
*/
class ProcessHandler: public Interfaced, public LastXCombInfo<> {
public:
/** A weighted list of pointers to StandardXComb objects. */
typedef Selector<StdXCombPtr> XSelector;
/** A vector of pointers to StandardXComb objects. */
typedef vector<StdXCombPtr> XVector;
/** A vector of cross sections. */
typedef vector<CrossSection> XSVector;
/** Map of pointers to StandardXComb objects indexed by pointers to
* the corresponding MEBase object. */
typedef map<tMEPtr,XVector> MEXMap;
public:
- /** @name Standard constructors and destructors. */
- //@{
/**
* The default constructor.
*/
ProcessHandler();
- /**
- * The copy constructor.
- */
- ProcessHandler(const ProcessHandler &);
-
- /**
- * The destructor.
- */
- virtual ~ProcessHandler();
- //@}
-
public:
/** @name Methods for the MPI generation. */
//@{
/**
* Select a StandardXComb according to it's weight
* @return that StandardXComb Object
*/
inline tStdXCombPtr generate();
//@}
/** @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();
/**
* Initialize this Multiple Interaction handler and all related objects needed to
* generate additional events.
*/
void initialize(tSubHdlPtr sub, tCutsPtr cuts, tEHPtr eh);
/**
* Return the integrated cross section.
*/
CrossSection integratedXSec() const;
/**
* Write out accumulated statistics about intergrated cross sections
* and stuff.
*/
void statistics(ostream &, Stat &) const;
/** @name Functions used for the actual generation */
//@{
/**
* Return the cross section for the chosen phase space point.
* @param r a vector of random numbers to be used in the generation
* of a phase space point.
*/
virtual CrossSection dSigDR(const vector<double> & r);
/** @name Simple access functions. */
//@{
/**
* The level of statistics. Controlls the amount of statistics
* written out after each run to the <code>EventGenerator</code>s
* <code>.out</code> file. Simply the EventHandler method is called here.
*/
inline int statLevel() const;
/**
* The pair of incoming particle types obtained via the EventHandler
*/
inline const cPDPair & incoming() const;
/**
* Access the luminosity function via the EventHandler.
*/
inline const LuminosityFunction & lumiFn() const;
/**
* The number of phase space dimensions used by the luminosity
* function. Calls the corresponding StandardEventHandler method.
*/
inline int lumiDim() const;
/**
* Return the number of separate bins of StandardXComb objects to
* sample.
*/
int nBins() const;
/**
* Return the number of phase space dimensions needed for the
* sampling of indicated bin of StandardXComb objects.
*/
inline int maxDim(int bin) const;
/**
* The number of dimensions of the basic phase space to generate
* sub-processes in for a given bin of StandardXComb objects.
*/
inline int nDim(int bin) const;
/**
* Return the maximum number attemts allowed to select a sub-process
* for each event. Calls the corresponding StandardEventHandler method.
*/
inline long maxLoop() const;
protected:
/**
* Generate a phase space point and return the corresponding cross
* section. Is called from sSigDR(const vector<double> &).
* @param ll a pair of doubles giving the logarithms of the (inverse
* energy fractions of the maximum CMS energy of the incoming
* particles.
* @param maxS the maximum squared CMS energy of the incoming particles.
* @param ibin the preselected bin of StandardXComb objects to choose
* sub-process from
* @param nr the number of random numbers availiable in \a r.
* @param r an array of random numbers to be used to generate a
* phase-space point.
*/
virtual CrossSection dSigDR(const pair<double,double> ll, Energy2 maxS,
int ibin, int nr, const double * r);
/**
* Select an StandardXComb. Given a preselected bin, \a ibin of
* StandardXComb objects pick one to generate the corresponding
* sub-process with the given \a weight.
*/
tStdXCombPtr select(int bin, double weight);
/**
* Create and add <code>StandardXComb</code> objects.
*
* @param maxEnergy the maximum CMS energy of the incoming particles.
* @param sub a pointer to the SubProcessHandler object.
* @param extractor a pointer to the PartonExtractor object.
* @param cuts a pointer to the Cuts object.
* @param ckkw a currently empty pointer to a CascadeHandler to be used for CKKW reweighting.
* @param me a pointer to the MEBase object.
* @param pBins a pair of <code>PartonBin</code>s describing the
* partons extracted from the particles
*/
void addME(Energy maxEnergy, tSubHdlPtr sub, tPExtrPtr extractor, tCutsPtr cuts,
tCascHdlPtr ckkw, tMEPtr me, const PBPair & pBins);
/**
* Return the vector of StandardXComb objects.
*/
inline const XVector & xCombs() const;
/**
* Return the vector of StandardXComb objects.
*/
inline XVector & xCombs();
/**
* Return the vector of cross sections.
*/
inline const XSVector & xSecs() const;
/**
* Return the vector of cross sections.
*/
inline XSVector & xSecs();
/**
* Return the strategy to be used when sampling different StandardXComb
* objects.
* @return 0 if all StandardXComb objects are sampled together. 1 if
* all StandardXComb objects which have the same matrix element object are
* sampled together. 2 if all StandardXComb objects are sampled separately.
*/
inline int binStrategy() const;
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
inline 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.
*/
inline virtual IBPtr fullclone() const;
//@}
private:
/**
* Return the ThePEG::EventHandler assigned to this handler.
* This methods shadows ThePEG::StepHandler::eventHandler(), because
* it is not virtual in ThePEG::StepHandler. This is ok, because this
* method would give a null-pointer at some stages, whereas this method
* gives access to the explicitely copied pointer (in doinitrun())
* to the ThePEG::EventHandler.
*/
inline tEHPtr eventHandler() const;
/**
* Return the sampler assigned to this handler.
*/
inline tSamplerPtr sampler();
/**
* Return the sampler assigned to this handler.
*/
inline tcSamplerPtr sampler() const;
/**
* Return a reference to the Cuts of this
* MultipleInteractionHandler. Note that these cuts may be overridden by the
* SubProcess chosen.
*/
inline tCutsPtr cuts() const;
/**
* Access the sub-process handler.
*/
inline tSubHdlPtr subProcess();
protected:
/** @name Standard Interfaced functions. */
//@{
/**
* Initialize this object. Called in the run phase just before
* a run begins.
*/
virtual void doinitrun();
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
ProcessHandler & operator=(const ProcessHandler &) = delete;
/**
* The phase space sampler responsible for generating phase space
* points according to the cross section given by this handler.
*/
SamplerPtr theSampler;
/**
* A pointer to the EventHandler that calls us. Has to be saved, because the
* method eventHandler() inherited from ThePEG::StepHandler returns a null-pointer
* sometimes. Leif changed that in r1053 so that a valid pointer is present, when
* calling doinitrun().
*/
tEHPtr theHandler;
/**
* The kinematical cuts used for this collision handler.
*/
tCutsPtr theCuts;//used a transient pointer,
//because regular pointer is already in MPIHandler
/**
* The SubProcessHandler that is connected to this ProcessHandler.
*/
tSubHdlPtr theSubProcess;//used a transient pointer,
//because regular pointer is already in MPIHandler
/**
* The StandardXComb objects.
*/
XVector theXCombs;
/**
* The (incrementally summed) cross sections associated with the
* StandardXComb objects for the last selected phase space point.
*/
XSVector theXSecs;
/**
* The strategy to be used when sampling different StandardXComb
* objects. 0 means all StandardXComb objects are sampled
* together. 1 means all StandardXComb objects which have the same
* matrix element object are sampled together. 2 means all
* StandardXComb objects are sampled separately.
*/
int theBinStrategy;
/**
* The map used to store all XBins with the same matrix element for
* option 1 in theBinStrategy.
*/
MEXMap theMEXMap;
/**
* The number of degrees of freedom needed to generate the phase
* space for the different bins.
*/
vector<int> theMaxDims;
protected:
/** @cond EXCEPTIONCLASSES */
/**
* Exception class used by the MultipleInteractionHandler, when something
* during initialization went wrong.
* \todo understand!!!
*/
class InitError: public Exception {};
/** @endcond */
};
}
#include "ProcessHandler.icc"
#endif /* HERWIG_ProcessHandler_H */
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -1,271 +1,270 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
AC_INIT([Herwig],[devel],[herwig@projects.hepforge.org],[Herwig])
AC_CONFIG_SRCDIR([Utilities/HerwigStrategy.cc])
AC_CONFIG_AUX_DIR([Config])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([Config/config.h])
dnl AC_PRESERVE_HELP_ORDER
AC_CANONICAL_HOST
dnl === disable debug symbols by default =====
if test "x$CXXFLAGS" = "x"; then
CXXFLAGS="-O2 -DBOOST_UBLAS_NDEBUG"
fi
if test "x$CFLAGS" = "x"; then
CFLAGS=-O2
fi
AC_LANG([C++])
AM_INIT_AUTOMAKE([1.11 subdir-objects gnu dist-bzip2 no-dist-gzip -Wall -Wno-portability])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
dnl Checks for C++ compiler. Handle C++11 flags.
AC_PROG_CXX
AX_CXX_COMPILE_STDCXX([11],[noext],[mandatory])
dnl check for POSIX
AC_CHECK_HEADER([unistd.h],[],
[AC_MSG_ERROR([Herwig needs "unistd.h". Non-POSIX systems are not supported.])])
AC_CHECK_HEADER([sys/stat.h],[],
[AC_MSG_ERROR([Herwig needs "sys/stat.h". Non-POSIX systems are not supported.])])
dnl Checks for programs.
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_LN_S
dnl modified search order
AC_PROG_FC([gfortran g95 g77])
dnl xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn xlf90 f90 pgf90 pghpf epcf90 xlf f77 frt pgf77 cf77 fort77 fl32 af77])
AC_LANG_PUSH([Fortran])
AC_MSG_CHECKING([if the Fortran compiler ($FC) works])
AC_COMPILE_IFELSE(
AC_LANG_PROGRAM([],[ print *[,]"Hello"]),
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([A Fortran compiler is required to build Herwig.])
]
)
AC_LANG_POP([Fortran])
AC_FC_WRAPPERS
LT_PREREQ([2.2.6])
LT_INIT([disable-static dlopen pic-only])
dnl ####################################
dnl ####################################
dnl for Doc/fixinterfaces.pl
AC_PATH_PROG(PERL, perl)
dnl for Models/Feynrules
AM_PATH_PYTHON([2.6],, [:])
AM_CONDITIONAL([HAVE_PYTHON], [test "x$PYTHON" != "x:"])
HERWIG_CHECK_GSL
HERWIG_CHECK_THEPEG
BOOST_REQUIRE([1.41])
BOOST_FIND_HEADER([boost/numeric/ublas/io.hpp])
dnl Boost 1.64 is missing a required header to make these work
dnl we just assume they're there if io.hpp has been found OK above
dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix.hpp])
dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix_proxy.hpp])
dnl BOOST_FIND_HEADER([boost/numeric/ublas/matrix_sparse.hpp])
dnl BOOST_FIND_HEADER([boost/numeric/ublas/symmetric.hpp])
dnl BOOST_FIND_HEADER([boost/numeric/ublas/vector.hpp])
BOOST_FIND_HEADER([boost/operators.hpp])
BOOST_TEST()
HERWIG_CHECK_VBFNLO
HERWIG_CHECK_NJET
HERWIG_CHECK_GOSAM
HERWIG_CHECK_GOSAM_CONTRIB
HERWIG_CHECK_OPENLOOPS
HERWIG_CHECK_MADGRAPH
HERWIG_CHECK_EVTGEN
HERWIG_CHECK_PYTHIA
HERWIG_COMPILERFLAGS
HERWIG_LOOPTOOLS
FASTJET_CHECK_FASTJET
HERWIG_ENABLE_MODELS
SHARED_FLAG=-shared
AM_CONDITIONAL(NEED_APPLE_FIXES,
[test "xx${host/darwin/foundit}xx" != "xx${host}xx"])
if test "xx${host/darwin/foundit}xx" != "xx${host}xx"; then
APPLE_DSO_FLAGS=-Wl,-undefined,dynamic_lookup
SHARED_FLAG=-bundle
fi
AC_SUBST([APPLE_DSO_FLAGS])
AC_SUBST([SHARED_FLAG])
AC_SUBST([PYTHON])
AC_CONFIG_FILES([UnderlyingEvent/Makefile
Models/Makefile
Models/StandardModel/Makefile
Models/RSModel/Makefile
Models/General/Makefile
Models/Susy/Makefile
Models/Susy/NMSSM/Makefile
Models/Susy/RPV/Makefile
Models/UED/Makefile
Models/LH/Makefile
Models/DarkMatter/Makefile
Models/LHTP/Makefile
Models/Transplanckian/Makefile
Models/Leptoquarks/Makefile
Models/Zprime/Makefile
Models/TTbAsymm/Makefile
Models/Feynrules/Makefile
Models/Feynrules/python/Makefile-FR
Models/ADD/Makefile
Models/Sextet/Makefile
Decay/Makefile
Decay/FormFactors/Makefile
Decay/Tau/Makefile
Decay/Baryon/Makefile
Decay/VectorMeson/Makefile
Decay/Perturbative/Makefile
Decay/HeavyMeson/Makefile
Decay/ScalarMeson/Makefile
Decay/Dalitz/Makefile
Decay/TensorMeson/Makefile
Decay/WeakCurrents/Makefile
Decay/Partonic/Makefile
Decay/General/Makefile
Decay/Radiation/Makefile
Decay/EvtGen/Makefile
Doc/refman.conf
Doc/refman.h
PDT/Makefile
PDF/Makefile
MatrixElement/Makefile
MatrixElement/General/Makefile
MatrixElement/Lepton/Makefile
MatrixElement/Hadron/Makefile
MatrixElement/DIS/Makefile
MatrixElement/Powheg/Makefile
MatrixElement/Gamma/Makefile
MatrixElement/Reweighters/Makefile
- MatrixElement/EW/Makefile
MatrixElement/Matchbox/Makefile
MatrixElement/Matchbox/Base/Makefile
MatrixElement/Matchbox/Utility/Makefile
MatrixElement/Matchbox/Phasespace/Makefile
MatrixElement/Matchbox/Dipoles/Makefile
MatrixElement/Matchbox/InsertionOperators/Makefile
MatrixElement/Matchbox/Matching/Makefile
MatrixElement/Matchbox/Cuts/Makefile
MatrixElement/Matchbox/Scales/Makefile
MatrixElement/Matchbox/ColorFull/Makefile
MatrixElement/Matchbox/CVolver/Makefile
MatrixElement/Matchbox/Builtin/Makefile
MatrixElement/Matchbox/Builtin/Amplitudes/Makefile
MatrixElement/Matchbox/Tests/Makefile
MatrixElement/Matchbox/External/Makefile
MatrixElement/Matchbox/External/BLHAGeneric/Makefile
MatrixElement/Matchbox/External/VBFNLO/Makefile
MatrixElement/Matchbox/External/NJet/Makefile
MatrixElement/Matchbox/External/GoSam/Makefile
MatrixElement/Matchbox/External/OpenLoops/Makefile
MatrixElement/Matchbox/External/MadGraph/Makefile
MatrixElement/Matchbox/External/MadGraph/mg2herwig
MatrixElement/Matchbox/External/GoSam/gosam2herwig.py
MatrixElement/FxFx/Makefile
Sampling/Makefile
Sampling/CellGrids/Makefile
Shower/Makefile
Shower/QTilde/Makefile
Shower/QTilde/Matching/Makefile
Shower/Dipole/Makefile
Shower/Dipole/Base/Makefile
Shower/Dipole/Kernels/Makefile
Shower/Dipole/Kinematics/Makefile
Shower/Dipole/Utility/Makefile
Shower/Dipole/AlphaS/Makefile
Shower/Dipole/SpinCorrelations/Makefile
Utilities/Makefile
Utilities/XML/Makefile
Utilities/Statistics/Makefile
Hadronization/Makefile
lib/Makefile
include/Makefile
src/Makefile
src/defaults/Makefile
src/snippets/Makefile
src/Matchbox/Makefile
src/herwig-config
Doc/Makefile
Doc/HerwigDefaults.in
Looptools/Makefile
Analysis/Makefile
API/Makefile
src/Makefile-UserModules
src/defaults/Analysis.in
src/defaults/MatchboxDefaults.in
src/defaults/Decays.in
src/defaults/decayers.in
src/defaults/setup.gosam.in
src/Matchbox/LO-DefaultShower.in
src/Matchbox/LO-DipoleShower.in
src/Matchbox/MCatLO-DefaultShower.in
src/Matchbox/MCatLO-DipoleShower.in
src/Matchbox/LO-NoShower.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/Merging/Makefile
Shower/Dipole/Merging/Makefile
src/defaults/MatchboxMergingDefaults.in
Contrib/Makefile
Contrib/make_makefiles.sh
Tests/Makefile
Makefile])
AC_CONFIG_FILES([Tests/python/rivet_check ],[chmod +x Tests/python/rivet_check ])
AC_CONFIG_FILES([Tests/python/LowEnergy-EE.py ],[chmod +x Tests/python/LowEnergy-EE.py ])
AC_CONFIG_FILES([Tests/python/LowEnergy-Photon.py],[chmod +x Tests/python/LowEnergy-Photon.py])
AC_CONFIG_FILES([Tests/python/make_input_files.py],[chmod +x Tests/python/make_input_files.py])
AC_CONFIG_FILES([Tests/python/merge-DIS ],[chmod +x Tests/python/merge-DIS ])
AC_CONFIG_FILES([Tests/python/merge-EE ],[chmod +x Tests/python/merge-EE ])
AC_CONFIG_FILES([Tests/python/merge-EE-Gamma ],[chmod +x Tests/python/merge-EE-Gamma ])
AC_CONFIG_FILES([Tests/python/merge-Fixed ],[chmod +x Tests/python/merge-Fixed ])
AC_CONFIG_FILES([Tests/python/merge-GammaGamma ],[chmod +x Tests/python/merge-GammaGamma ])
AC_CONFIG_FILES([Tests/python/merge-LHC-EW ],[chmod +x Tests/python/merge-LHC-EW ])
AC_CONFIG_FILES([Tests/python/merge-LHC-Jets ],[chmod +x Tests/python/merge-LHC-Jets ])
AC_CONFIG_FILES([Tests/python/merge-LHC-Photon ],[chmod +x Tests/python/merge-LHC-Photon ])
AC_CONFIG_FILES([Tests/python/mergeLowEnergy.py ],[chmod +x Tests/python/mergeLowEnergy.py ])
AC_CONFIG_FILES([Tests/python/merge-Star ],[chmod +x Tests/python/merge-Star ])
AC_CONFIG_FILES([Tests/python/merge-TVT-EW ],[chmod +x Tests/python/merge-TVT-EW ])
AC_CONFIG_FILES([Tests/python/merge-TVT-Jets ],[chmod +x Tests/python/merge-TVT-Jets ])
AC_CONFIG_FILES([Tests/python/merge-TVT-Photon ],[chmod +x Tests/python/merge-TVT-Photon ])
AC_CONFIG_FILES([Tests/python/plot-EE ],[chmod +x Tests/python/plot-EE ])
AC_CONFIG_FILES([Tests/python/R.py ],[chmod +x Tests/python/R.py ])
AC_CONFIG_FILES([Sampling/herwig-mergegrids.py ],[chmod +x Sampling/herwig-mergegrids.py ])
AC_CONFIG_LINKS([Doc/BSMlibs.in:Doc/BSMlibs.in])
AC_CONFIG_FILES([Doc/fixinterfaces.pl],[chmod +x Doc/fixinterfaces.pl])
AC_CONFIG_HEADERS([PDF/SaSPhotonPDF.cc])
HERWIG_OVERVIEW
AC_CONFIG_COMMANDS([summary],[cat config.herwig])
AC_OUTPUT
diff --git a/m4/herwig.m4 b/m4/herwig.m4
--- a/m4/herwig.m4
+++ b/m4/herwig.m4
@@ -1,1009 +1,1009 @@
dnl ##### THEPEG #####
AC_DEFUN([HERWIG_CHECK_THEPEG],
[
defaultlocation="${prefix}"
test "x$defaultlocation" = xNONE && defaultlocation="${ac_default_prefix}"
AC_MSG_CHECKING([for libThePEG in])
AC_ARG_WITH(thepeg,
AC_HELP_STRING([--with-thepeg=DIR],[location of ThePEG installation]),
[],
[with_thepeg="${defaultlocation}"])
AC_MSG_RESULT([$with_thepeg])
if test "x$with_thepeg" = "xno"; then
AC_MSG_ERROR([Cannot build Herwig without ThePEG. Please set --with-thepeg.])
fi
THEPEGLDFLAGS="-L${with_thepeg}/lib/ThePEG"
THEPEGHASLHAPDF="no"
if test -e ${with_thepeg}/lib/ThePEG/ThePEGLHAPDF.so ; then
THEPEGHASLHAPDF="yes"
fi
if test "${host_cpu}" == "x86_64" -a -e ${with_thepeg}/lib64/ThePEG/libThePEG.so ; then
THEPEGLDFLAGS="-L${with_thepeg}/lib64/ThePEG"
if test -e ${with_thepeg}/lib64/ThePEG/ThePEGLHAPDF.so ; then
THEPEGHASLHAPDF="yes"
fi
fi
if test "x$THEPEGHASLHAPDF" == "xno" ; then
AC_MSG_ERROR([Herwig requires ThePEG to be build with lhapdf.])
fi
THEPEGHASFASTJET="no"
if test -e ${with_thepeg}/lib/ThePEG/FastJetFinder.so ; then
THEPEGHASFASTJET="yes"
fi
if test "${host_cpu}" == "x86_64" -a -e ${with_thepeg}/lib64/ThePEG/libThePEG.so ; then
THEPEGLDFLAGS="-L${with_thepeg}/lib64/ThePEG"
if test -e ${with_thepeg}/lib64/ThePEG/FastJetFinder.so ; then
THEPEGHASFASTJET="yes"
fi
fi
if test "x$THEPEGHASFASTJET" == "xno" ; then
AC_MSG_ERROR([Herwig requires ThePEG to be build with FastJet.])
fi
THEPEGPATH="${with_thepeg}"
oldldflags="$LDFLAGS"
oldlibs="$LIBS"
LDFLAGS="$LDFLAGS $THEPEGLDFLAGS"
AC_CHECK_LIB([ThePEG],[debugThePEG],[],
[AC_MSG_ERROR([No ThePEG libraries in $THEPEGLDFLAGS. Please set --with-thepeg.])])
AC_SUBST([THEPEGLIB],[-lThePEG])
AC_SUBST(THEPEGLDFLAGS)
AC_SUBST(THEPEGPATH)
AC_SUBST(THEPEGHASLHAPDF)
AC_SUBST(THEPEGHASFASTJET)
LIBS="$oldlibs"
LDFLAGS="$oldldflags"
AC_MSG_CHECKING([for ThePEG headers in])
AC_ARG_WITH([thepeg-headers],
AC_HELP_STRING([--with-thepeg-headers=DIR],[location of ThePEG include directory]),
[],
[with_thepeg_headers="${with_thepeg}/include"])
AC_MSG_RESULT([$with_thepeg_headers])
if test "x$with_thepeg_headers" = "xno"; then
AC_MSG_ERROR([Cannot build Herwig without ThePEG headers. Please set --with-thepeg-headers.])
fi
THEPEGINCLUDE="-I$with_thepeg_headers"
oldcppflags="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $THEPEGINCLUDE"
AC_CHECK_HEADER([ThePEG/Config/ThePEG.h],[],
[AC_MSG_ERROR([No ThePEG headers in $with_thepeg_headers. Please set --with-thepeg-headers.])])
CPPFLAGS="$oldcppflags"
AC_SUBST(THEPEGINCLUDE)
AC_MSG_CHECKING([for HepMCAnalysis.so in ThePEG])
THEPEGHASHEPMC="no"
if test -e ${with_thepeg}/lib/ThePEG/HepMCAnalysis.so ; then
THEPEGHASHEPMC="yes"
fi
if test "${host_cpu}" == "x86_64" -a -e ${with_thepeg}/lib64/ThePEG/libThePEG.so ; then
THEPEGLDFLAGS="-L${with_thepeg}/lib64/ThePEG"
if test -e ${with_thepeg}/lib64/ThePEG/HepMCAnalysis.so ; then
THEPEGHASHEPMC="yes"
fi
fi
if test "x$THEPEGHASHEPMC" == "xno" ; then
CREATE_HEPMC="# create"
AC_MSG_RESULT([not found])
else
CREATE_HEPMC="create"
AC_MSG_RESULT([found])
fi
AC_SUBST([CREATE_HEPMC])
AC_MSG_CHECKING([for RivetAnalysis.so in ThePEG])
THEPEGHASRIVET="no"
if test -e ${with_thepeg}/lib/ThePEG/RivetAnalysis.so ; then
THEPEGHASRIVET="yes"
fi
if test "${host_cpu}" == "x86_64" -a -e ${with_thepeg}/lib64/ThePEG/libThePEG.so ; then
THEPEGLDFLAGS="-L${with_thepeg}/lib64/ThePEG"
if test -e ${with_thepeg}/lib64/ThePEG/RivetAnalysis.so ; then
THEPEGHASRIVET="yes"
fi
fi
if test "x$THEPEGHASRIVET" == "xno" ; then
CREATE_RIVET="# create"
AC_MSG_RESULT([not found])
else
CREATE_RIVET="create"
AC_MSG_RESULT([found])
fi
AM_CONDITIONAL(HAVE_RIVET,[test x$THEPEGHASRIVET = xyes])
AC_SUBST([CREATE_RIVET])
])
dnl ##### LOOPTOOLS #####
AC_DEFUN([HERWIG_LOOPTOOLS],
[
AC_REQUIRE([AC_PROG_FC])
AC_REQUIRE([AC_FC_LIBRARY_LDFLAGS])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([HERWIG_COMPILERFLAGS])
AC_MSG_CHECKING([if Looptools build works])
enable_looptools=yes
if test "x$GCC" = "xyes"; then
case "${host}" in
x86_64-*|*-darwin1*)
AM_FCFLAGS="$AM_FCFLAGS -fdefault-integer-8"
;;
esac
AC_LANG_PUSH([Fortran])
oldFCFLAGS="$FCFLAGS"
FCFLAGS="$AM_FCFLAGS"
AC_COMPILE_IFELSE(
AC_LANG_PROGRAM([],[ print *[,]"Hello"]),
[],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([needs gfortran on 64bit machines])]
)
FCFLAGS="$oldFCFLAGS"
AC_LANG_POP([Fortran])
fi
AC_MSG_RESULT([$enable_looptools])
AC_LANG_PUSH([Fortran])
AC_MSG_CHECKING([checking if fortran compiler compiles argument mismatches])
AC_COMPILE_IFELSE(AC_LANG_SOURCE([[
program temp
call a(1.0D0)
end program
subroutine a(b)
double complex b
end]]),
[AC_MSG_RESULT([yes])],
[oldFCFLAGS="$FCFLAGS"
FCFLAGS="-std=legacy"
AC_MSG_CHECKING([checking if fortran compiler compiles argument mismatches with -std=legacy])
AC_COMPILE_IFELSE(AC_LANG_SOURCE([[
program temp
double precision b
double complex c
b = 1.0D0
c =1.0D0
call a(b)
call a(c)
end program
subroutine a(b)
double complex b
end]]),
[AC_MSG_RESULT([yes])
AM_FCFLAGS="$AM_FCFLAGS -std=legacy"],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([fortran compiler won't compile LoopTools])])
FCFLAGS="$oldFCFLAGS -std=legacy"]
)
AC_MSG_CHECKING([checking if fortran compiler compiles long lines])
AC_COMPILE_IFELSE(AC_LANG_SOURCE([[
program temp
write (*,*) 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
end program]]),
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
oldFCFLAGS="$FCFLAGS"
FCFLAGS="-ffixed-line-length-none"
AC_MSG_CHECKING([checking if fortran compiler compiles long lines with -ffixed-line-length-none])
AC_COMPILE_IFELSE(AC_LANG_SOURCE([[
program temp
write (*,*) 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
end program]]),
[AC_MSG_RESULT([yes])
AM_FCFLAGS="$AM_FCFLAGS -ffixed-line-length-none"
FCFLAGS="$oldFCFLAGS -ffixed-line-length-none"],
[FCFLAGS="-132"
AC_MSG_CHECKING([checking if fortran compiler compiles long lines with -132])
AC_COMPILE_IFELSE(AC_LANG_SOURCE([[
program temp
write (*,*) 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
end program]]),
[AC_MSG_RESULT([yes])
AM_FCFLAGS="$AM_FCFLAGS -132"
FCFLAGS="$oldFCFLAGS -132"],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([fortran compiler won't compile LoopTools])])])
]
)
AC_LANG_POP([Fortran])
AC_SUBST([F77],[$FC])
AC_SUBST([FFLAGS],[$FCFLAGS])
AC_SUBST([AM_FFLAGS],[$AM_FCFLAGS])
AC_SUBST([FLIBS],[$FCLIBS])
])
dnl ##### VBFNLO #####
AC_DEFUN([HERWIG_CHECK_VBFNLO],
[
AC_MSG_CHECKING([for VBFNLO])
AC_ARG_WITH([vbfnlo],
AS_HELP_STRING([--with-vbfnlo=DIR], [Installation path of VBFNLO]),
[],
[with_vbfnlo=no]
)
AC_MSG_RESULT([$with_vbfnlo])
AS_IF([test "x$with_vbfnlo" != "xno"],
[AC_CHECK_FILES(
${with_vbfnlo}/lib/VBFNLO/libVBFNLO.so,
[have_vbfnlo=lib], [have_vbfnlo=no])],
[have_vbfnlo=no])
AS_IF([test "x$with_vbfnlo" != "xno" -a "x$have_vbfnlo" = "xno" ],
[AC_CHECK_FILES(
${with_vbfnlo}/lib64/VBFNLO/libVBFNLO.so,
[have_vbfnlo=lib64], [have_vbfnlo=no])])
AS_IF([test "x$with_vbfnlo" != "xno" -a "x$have_vbfnlo" = "xno" ],
[AC_CHECK_FILES(
${with_vbfnlo}/lib/VBFNLO/libVBFNLO.dylib,
[have_vbfnlo=lib], [have_vbfnlo=no])])
AS_IF([test "x$with_vbfnlo" != "xno" -a "x$have_vbfnlo" = "xno" ],
[AC_CHECK_FILES(
${with_vbfnlo}/lib64/VBFNLO/libVBFNLO.dylib,
[have_vbfnlo=lib64], [have_vbfnlo=no])])
AS_IF([test "x$have_vbfnlo" = "xlib"],
[VBFNLOLIBS=${with_vbfnlo}/lib/VBFNLO
AC_SUBST(VBFNLOLIBS)
])
AS_IF([test "x$have_vbfnlo" = "xlib64"],
[VBFNLOLIBS=${with_vbfnlo}/lib64/VBFNLO
AC_SUBST(VBFNLOLIBS)
])
AS_IF([test "x$with_vbfnlo" != "xno" -a "x$have_vbfnlo" = "xno"],
[AC_MSG_ERROR([vbfnlo requested but not found])])
AM_CONDITIONAL(HAVE_VBFNLO,[test "x$have_vbfnlo" = "xlib" -o "x$have_vbfnlo" = "xlib64"])
if test "x$have_vbfnlo" = "xlib" -o "x$have_vbfnlo" = "xlib64" ; then
AC_REQUIRE([AC_PROG_SED])
VBFNLOINCLUDE=${with_vbfnlo}/include
AC_SUBST(VBFNLOINCLUDE)
VBFNLOLIB=$(echo ${with_vbfnlo}/${have_vbfnlo}/VBFNLO | $SED -e 's%/\+%/%g')
AC_SUBST(VBFNLOLIB)
LOAD_VBFNLO="library"
CREATE_VBFNLO="create"
INSERT_VBFNLO="insert"
SET_VBFNLO="set"
DO_VBFNLO="do"
MKDIR_VBFNLO="mkdir"
else
LOAD_VBFNLO="# library"
CREATE_VBFNLO="# create"
INSERT_VBFNLO="# insert"
SET_VBFNLO="# set"
DO_VBFNLO="# do"
MKDIR_VBFNLO="# mkdir"
fi
AC_SUBST([LOAD_VBFNLO])
AC_SUBST([CREATE_VBFNLO])
AC_SUBST([INSERT_VBFNLO])
AC_SUBST([SET_VBFNLO])
AC_SUBST([DO_VBFNLO])
AC_SUBST([MKDIR_VBFNLO])
])
dnl ##### njet #####
AC_DEFUN([HERWIG_CHECK_NJET],
[
AC_MSG_CHECKING([for njet])
AC_ARG_WITH([njet],
AS_HELP_STRING([--with-njet=DIR], [Installation path of njet]),
[],
[with_njet=no]
)
AC_MSG_RESULT([$with_njet])
AS_IF([test "x$with_njet" != "xno"],
[AC_CHECK_FILES(
${with_njet}/lib/libnjet2.so,
[have_njet=lib], [have_njet=no])],
[have_njet=no])
AS_IF([test "x$with_njet" != "xno" -a "x$have_njet" = "xno" ],
[AC_CHECK_FILES(
${with_njet}/lib64/libnjet2.so,
[have_njet=lib64], [have_njet=no])])
AS_IF([test "x$with_njet" != "xno" -a "x$have_njet" = "xno" ],
[AC_CHECK_FILES(
${with_njet}/lib/libnjet2.dylib,
[have_njet=lib], [have_njet=no])])
AS_IF([test "x$with_njet" != "xno" -a "x$have_njet" = "xno" ],
[AC_CHECK_FILES(
${with_njet}/lib/libnjet3.so,
[have_njet=lib], [have_njet=no])])
AS_IF([test "x$with_njet" != "xno" -a "x$have_njet" = "xno" ],
[AC_CHECK_FILES(
${with_njet}/lib64/libnjet3.so,
[have_njet=lib], [have_njet=no])])
AS_IF([test "x$with_njet" != "xno" -a "x$have_njet" = "xno" ],
[AC_CHECK_FILES(
${with_njet}/lib/libnjet3.dylib,
[have_njet=lib], [have_njet=no])])
AS_IF([test "x$with_njet" != "xno" ],
[AC_CHECK_FILES(
${with_njet}/include/njet.h,
[njet_include=include], [njet_include=include/njet])])
AS_IF([test "x$have_njet" = "xlib"],
[NJETLIBPATH=${with_njet}/lib
AC_SUBST(NJETLIBPATH)
NJETINCLUDEPATH=${with_njet}/$njet_include
AC_SUBST(NJETINCLUDEPATH)
NJETPREFIX=${with_njet}
AC_SUBST(NJETPREFIX)
])
AS_IF([test "x$have_njet" = "xlib64"],
[NJETLIBPATH=${with_njet}/lib64
AC_SUBST(NJETLIBPATH)
NJETINCLUDEPATH=${with_njet}/$njet_include
AC_SUBST(NJETINCLUDEPATH)
NJETPREFIX=${with_njet}
AC_SUBST(NJETPREFIX)
])
AS_IF([test "x$with_njet" != "xno" -a "x$have_njet" = "xno"],
[AC_MSG_ERROR([njet requested but not found])])
AM_CONDITIONAL(HAVE_NJET,[test "x$have_njet" = "xlib" -o "x$have_njet" = "xlib64"])
AS_IF([test "x$with_njet" != "xno"],[AC_MSG_CHECKING([for Njet version])
tmp_njetversion=[$(${with_njet}/bin/njet.py --version 2>&1 | grep -oE '[0-9]{4}$')]
AS_IF([test -z "$tmp_njetversion"],
[tmp_njetversion=1023])
AC_MSG_RESULT([${tmp_njetversion}])
NJET_VERSION=${tmp_njetversion}
AC_SUBST(NJET_VERSION)
])
if test "x$have_njet" = "xlib" -o "x$have_njet" = "xlib64" ; then
LOAD_NJET="library"
CREATE_NJET="create"
INSERT_NJET="insert"
DO_NJET="do"
else
LOAD_NJET="# library"
CREATE_NJET="# create"
INSERT_NJET="# insert"
DO_NJET="# do"
fi
AC_SUBST([LOAD_NJET])
AC_SUBST([CREATE_NJET])
AC_SUBST([INSERT_NJET])
AC_SUBST([DO_NJET])
])
dnl ##### gosam #####
AC_DEFUN([HERWIG_CHECK_GOSAM],
[
AC_MSG_CHECKING([for GoSam])
AC_ARG_WITH([gosam],
AS_HELP_STRING([--with-gosam=DIR], [Installation path of GoSam]),
[],
[with_gosam=no]
)
AC_MSG_RESULT([$with_gosam])
AS_IF([test "x$with_gosam" != "xno"],
[AC_CHECK_FILES(
${with_gosam}/bin/gosam.py,
[have_gosam=lib], [have_gosam=no])],
[have_gosam=no])
AS_IF([test "x$have_gosam" = "xlib"],
[GOSAMPREFIX=${with_gosam}
AC_SUBST(GOSAMPREFIX)
])
AS_IF([test "x$with_gosam" != "xno" -a "x$have_gosam" = "xno"],
[AC_MSG_ERROR([GoSam requested but not found])])
AS_IF([test "x$with_gosam" != "xno"],
[AC_MSG_CHECKING([for GoSam version >= 2.0.4])
tmp_gosamversion=[$(${with_gosam}/bin/gosam.py --version | grep 'GoSam.*rev' | cut -d' ' -f2)]
AX_COMPARE_VERSION([${tmp_gosamversion}],[lt],[2.0.4],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([Herwig requires GoSam 2.0.4 or later, found ${tmp_gosamversion}])],
[AC_MSG_RESULT([yes])])])
AM_CONDITIONAL(HAVE_GOSAM,[test "x$have_gosam" = "xlib" ])
if test "x$have_gosam" = "xlib" ; then
LOAD_GOSAM="library"
CREATE_GOSAM="create"
INSERT_GOSAM="insert"
DO_GOSAM="do"
else
LOAD_GOSAM="# library"
CREATE_GOSAM="# create"
INSERT_GOSAM="# insert"
DO_GOSAM="# do"
fi
AC_SUBST([LOAD_GOSAM])
AC_SUBST([CREATE_GOSAM])
AC_SUBST([INSERT_GOSAM])
AC_SUBST([DO_GOSAM])
])
dnl ##### gosam-contrib #####
AC_DEFUN([HERWIG_CHECK_GOSAM_CONTRIB],
[
AC_MSG_CHECKING([for gosam-contrib])
AC_ARG_WITH([gosam-contrib],
AS_HELP_STRING([--with-gosam-contrib=DIR], [Installation path of gosam-contrib]),
[],
[with_gosam_contrib=no]
)
AC_MSG_RESULT([$with_gosam_contrib])
AS_IF([test "x$with_gosam_contrib" = "xno" -a "x$with_gosam" != "xno"],
[AC_CHECK_FILES(
${with_gosam}/lib/libsamurai.so,
[with_gosam_contrib=${with_gosam}], [])
])
AS_IF([test "x$with_gosam_contrib" = "xno" -a "x$with_gosam" != "xno"],
[AC_CHECK_FILES(
${with_gosam}/lib64/libsamurai.so,
[with_gosam_contrib=${with_gosam}], [])
])
AS_IF([test "x$with_gosam_contrib" = "xno" -a "x$with_gosam" != "xno"],
[AC_CHECK_FILES(
${with_gosam}/lib/libsamurai.dylib,
[with_gosam_contrib=${with_gosam}], [])
])
AS_IF([test "x$with_gosam_contrib" = "xno" -a "x$with_gosam" != "xno"],
[AC_CHECK_FILES(
${with_gosam}/lib64/libsamurai.dylib,
[with_gosam_contrib=${with_gosam}], [])
])
AS_IF([test "x$with_gosam_contrib" = "xno" -a "x$with_gosam" != "xno"],
[AC_MSG_ERROR([GoSam requested without requesting GoSam-Contrib])])
AS_IF([test "x$with_gosam_contrib" != "xno"],
[AC_CHECK_FILES(
${with_gosam_contrib}/lib/libsamurai.so,
[have_gosam_contrib=lib], [have_gosam_contrib=no])],
[have_gosam_contrib=no])
AS_IF([test "x$with_gosam_contrib" != "xno" -a "x$have_gosam_contrib" = "xno" ],
[AC_CHECK_FILES(
${with_gosam_contrib}/lib64/libsamurai.so,
[have_gosam_contrib=lib64], [have_gosam_contrib=no])])
AS_IF([test "x$with_gosam_contrib" != "xno" -a "x$have_gosam_contrib" = "xno" ],
[AC_CHECK_FILES(
${with_gosam_contrib}/lib/libsamurai.dylib,
[have_gosam_contrib=lib], [have_gosam_contrib=no])])
AS_IF([test "x$with_gosam_contrib" != "xno" -a "x$have_gosam_contrib" = "xno" ],
[AC_CHECK_FILES(
${with_gosam_contrib}/lib64/libsamurai.dylib,
[have_gosam_contrib=lib64], [have_gosam_contrib=no])])
AS_IF([test "x$have_gosam_contrib" != "xno"],
[GOSAMCONTRIBPREFIX=${with_gosam_contrib}
AC_SUBST(GOSAMCONTRIBPREFIX)
])
AS_IF([test "x$have_gosam_contrib" = "xlib"],
[GOSAMCONTRIBLIBS=${with_gosam_contrib}/lib
AC_SUBST(GOSAMCONTRIBLIBS)
])
AS_IF([test "x$have_gosam_contrib" = "xlib64"],
[GOSAMCONTRIBLIBS=${with_gosam_contrib}/lib64
AC_SUBST(GOSAMCONTRIBLIBS)
])
AS_IF([test "x$with_gosam_contrib" != "xno" -a "x$have_gosam_contrib" = "xno"],
[AC_MSG_ERROR([GoSam-Contrib requested but not found])])
AM_CONDITIONAL(HAVE_GOSAM_CONTRIB,[test "x$have_gosam_contrib" = "xlib" -o "x$have_gosam_contrib" = "xlib64"])
if test "x$have_gosam_contrib" = "xlib" -o "x$have_gosam_contrib" = "xlib64" ; then
LOAD_GOSAM_CONTRIB="library"
CREATE_GOSAM_CONTRIB="create"
INSERT_GOSAM_CONTRIB="insert"
else
LOAD_GOSAM_CONTRIB="# library"
CREATE_GOSAM_CONTRIB="# create"
INSERT_GOSAM_CONTRIB="# insert"
fi
AC_SUBST([LOAD_GOSAM_CONTRIB])
AC_SUBST([CREATE_GOSAM_CONTRIB])
AC_SUBST([INSERT_GOSAM_CONTRIB])
])
dnl ##### OpenLoops #####
AC_DEFUN([HERWIG_CHECK_OPENLOOPS],
[
AC_MSG_CHECKING([for OpenLoops])
AC_ARG_WITH([openloops],
AS_HELP_STRING([--with-openloops=DIR], [Installation path of OpenLoops]),
[],
[with_openloops=no]
)
AC_MSG_RESULT([$with_openloops])
AS_IF([test "x$with_openloops" != "xno"],
[AC_CHECK_FILES(
${with_openloops}/lib/libopenloops.so,
[have_openloops=lib], [have_openloops=no])],
[have_openloops=no])
AS_IF([test "x$with_openloops" != "xno" -a "x$have_openloops" = "xno" ],
[AC_CHECK_FILES(
${with_openloops}/lib/libopenloops.dylib,
[have_openloops=lib], [have_openloops=no])])
AS_IF([test "x$with_openloops" != "xno" -a "x$have_openloops" = "xno" ],
[AC_CHECK_FILES(
${with_openloops}/lib64/libopenloops.so,
[have_openloops=lib64], [have_openloops=no])])
AS_IF([test "x$with_openloops" != "xno" -a "x$have_openloops" = "xno" ],
[AC_CHECK_FILES(
${with_openloops}/lib64/libopenloops.dylib,
[have_openloops=lib64], [have_openloops=no])])
AS_IF([test "x$have_openloops" = "xlib"],
[OPENLOOPSLIBS=${with_openloops}/lib
AC_SUBST(OPENLOOPSLIBS)
])
AS_IF([test "x$have_openloops" = "xlib64"],
[OPENLOOPSLIBS=${with_openloops}/lib64
AC_SUBST(OPENLOOPSLIBS)
])
AS_IF([test "x$with_openloops" != "xno" -a "x$have_openloops" = "xno"],
[AC_MSG_ERROR([OpenLoops requested but not found])])
AM_CONDITIONAL(HAVE_OPENLOOPS,[test "x$have_openloops" = "xlib" -o "x$have_openloops" = "xlib64"])
if test "x$have_openloops" = "xlib" -o "x$have_openloops" = "xlib64" ; then
OPENLOOPSPREFIX=${with_openloops}
LOAD_OPENLOOPS="library"
CREATE_OPENLOOPS="create"
INSERT_OPENLOOPS="insert"
SET_OPENLOOPS="set"
DO_OPENLOOPS="do"
MKDIR_OPENLOOPS="mkdir"
else
LOAD_OPENLOOPS="# library"
CREATE_OPENLOOPS="# create"
INSERT_OPENLOOPS="# insert"
SET_OPENLOOPS="# set"
DO_OPENLOOPS="# do"
MKDIR_OPENLOOPS="# mkdir"
fi
AC_SUBST([OPENLOOPSPREFIX])
AC_SUBST([LOAD_OPENLOOPS])
AC_SUBST([CREATE_OPENLOOPS])
AC_SUBST([INSERT_OPENLOOPS])
AC_SUBST([SET_OPENLOOPS])
AC_SUBST([DO_OPENLOOPS])
AC_SUBST([MKDIR_OPENLOOPS])
])
#########################################
dnl ##### madgraph #####
AC_DEFUN([HERWIG_CHECK_MADGRAPH],
[
AC_MSG_CHECKING([for MadGraph])
AC_ARG_WITH([madgraph],
AS_HELP_STRING([--with-madgraph=DIR], [Installation path of MadGraph]),
[],
[with_madgraph=no]
)
AC_MSG_RESULT([$with_madgraph])
AS_IF([test "x$with_madgraph" != "xno"],
[AC_CHECK_FILES(
${with_madgraph}/bin/mg5_aMC,
[have_madgraph=yes], [have_madgraph=no])],
[have_madgraph=no])
AS_IF([test "x$have_madgraph" = "xyes"],
[MADGRAPHPREFIX=${with_madgraph}
AC_SUBST(MADGRAPHPREFIX)
])
AS_IF([test "x$with_madgraph" != "xno" -a "x$have_madgraph" = "xno"],
[AC_MSG_ERROR([MadGraph requested but not found])])
AM_CONDITIONAL(HAVE_MADGRAPH,[test "x$have_madgraph" = "xyes" ])
if test "x$have_madgraph" = "xyes" ; then
LOAD_MADGRAPH="library"
CREATE_MADGRAPH="create"
INSERT_MADGRAPH="insert"
SET_MADGRAPH="set"
DO_MADGRAPH="do"
else
LOAD_MADGRAPH="# library"
CREATE_MADGRAPH="# create"
INSERT_MADGRAPH="# insert"
SET_MADGRAPH="# set"
DO_MADGRAPH="# do"
fi
AC_SUBST([LOAD_MADGRAPH])
AC_SUBST([CREATE_MADGRAPH])
AC_SUBST([INSERT_MADGRAPH])
AC_SUBST([SET_MADGRAPH])
AC_SUBST([DO_MADGRAPH])
])
AC_DEFUN([HERWIG_CHECK_PYTHIA],
[
dnl check if a directory is specified for Pythia
AC_ARG_WITH(pythia,
[AC_HELP_STRING([--with-pythia=dir],
[Assume the given directory for Pythia])])
dnl search for the pythia-config script
if test "$with_pythia" = ""; then
AC_PATH_PROG(pythiaconfig, pythia8-config, no)
else
AC_PATH_PROG(pythiaconfig, pythia8-config, no, ${with_pythia}/bin)
fi
if test "${pythiaconfig}" = "no"; then
AC_MSG_CHECKING(Pythia)
AC_MSG_RESULT(no);
PYTHIA8LIB=
# $2
else
PYTHIA8DATA=`${pythiaconfig} --datadir`/xmldoc
PYTHIA8LIB="-L`${pythiaconfig} --libdir` -lpythia8"
fi
AC_SUBST(PYTHIA8DATA)
AC_SUBST(PYTHIA8LIB)
])
dnl CHECK PYTHIA END
dnl ##### EvtGen #####
AC_DEFUN([HERWIG_CHECK_EVTGEN],
[
AC_MSG_CHECKING([for evtgen])
AC_ARG_WITH([evtgen],
AS_HELP_STRING([--with-evtgen=DIR], [Installation path of EvtGen]),
[],
[with_evtgen=no]
)
AC_MSG_RESULT([$with_evtgen])
AS_IF([test "x$with_evtgen" != "xno"],
[AC_CHECK_FILES(
${with_evtgen}/lib/libEvtGenExternal.so,
[have_evtgen=lib], [have_evtgen=no])],
[have_evtgen=no])
AS_IF([test "x$with_evtgen" != "xno" -a "x$have_evtgen" = "xno"],
[AC_CHECK_FILES(
${with_evtgen}/lib64/libEvtGenExternal.so,
[have_evtgen=lib64], [have_evtgen=no])])
AS_IF([test "x$with_evtgen" != "xno" -a "x$have_evtgen" = "xno" ],
[AC_CHECK_FILES(
${with_evtgen}/lib/libEvtGenExternal.dylib,
[have_evtgen=lib], [have_evtgen=no])])
AS_IF([test "x$have_evtgen" = "xlib" -o "x$have_evtgen" = "xlib64" ],
[EVTGENPREFIX=${with_evtgen}
AC_SUBST(EVTGENPREFIX)
])
AS_IF([test "x$have_evtgen" = "xlib" -o "x$have_evtgen" = "xlib64" ],
[AC_CHECK_FILES(
${with_evtgen}/share/evt.pdl,
[EVTGENSHARE=${with_evtgen}/share], [EVTGENSHARE=${with_evtgen}/share/EvtGen])
AC_SUBST(EVTGENSHARE)])
AS_IF([test "x$with_evtgen" != "xno" -a "x$have_evtgen" = "xno"],
[AC_MSG_ERROR([EvtGen requested but not found])])
AC_SUBST([EVTGENINCLUDE],[-I$EVTGENPREFIX/include])
AM_CONDITIONAL(HAVE_EVTGEN,[test "x$have_evtgen" = "xlib" -o "x$have_evtgen" = "xlib64"])
if test "x$have_evtgen" = "xlib" ; then
LOAD_EVTGEN_DECAYS="read EvtGenBDecays.in"
LOAD_EVTGEN_DECAYER="read EvtGenDecayer.in"
EVTGENLIBS="-L$with_evtgen/lib -lEvtGen -lEvtGenExternal"
elif test "x$have_evtgen" = "xlib64" ; then
LOAD_EVTGEN_DECAYS="read EvtGenBDecays.in"
LOAD_EVTGEN_DECAYER="read EvtGenDecayer.in"
EVTGENLIBS="-L$with_evtgen/lib64 -lEvtGen -lEvtGenExternal"
else
LOAD_EVTGEN_DECAYS="read HerwigBDecays.in"
LOAD_EVTGEN_DECAYER="#read EvtGenDecayer.in"
EVTGENLIBS=""
fi
AC_SUBST([LOAD_EVTGEN_DECAYS])
AC_SUBST([LOAD_EVTGEN_DECAYER])
AC_SUBST([EVTGENLIBS])
])
dnl ###### GSL ######
AC_DEFUN([HERWIG_CHECK_GSL],
[
AC_MSG_CHECKING([for gsl location])
GSLINCLUDE=""
GSLLIBS=""
AC_ARG_WITH(gsl,
AC_HELP_STRING([--with-gsl=DIR],[location of gsl installation @<:@default=system libs@:>@]),
[],
[with_gsl=system])
if test "x$with_gsl" = "xno"; then
AC_MSG_ERROR([libgsl is required. Please install the GNU scientific library and header files.])
fi
if test "x$with_gsl" = "xsystem"; then
AC_MSG_RESULT([in system libraries])
oldlibs="$LIBS"
AC_CHECK_LIB(m,main)
AC_CHECK_LIB(gslcblas,main)
AC_CHECK_LIB(gsl,main,[],
[
AC_MSG_ERROR([Cannot find libgsl. Please install the GNU scientific library and header files or use --with-gsl=.])
]
)
GSLLIBS="$LIBS"
GSLPATH="$with_gsl"
LIBS=$oldlibs
else
if test "`uname -m`" = "x86_64" -a -e "$with_gsl/lib64/libgsl.a" -a -d "$with_gsl/include/gsl"; then
AC_MSG_RESULT([found in $with_gsl])
GSLLIBS="-L$with_gsl/lib64 -R$with_gsl/lib64 -lgslcblas -lgsl"
GSLINCLUDE="-I$with_gsl/include"
GSLPATH="$with_gsl"
elif test -e "$with_gsl/lib/libgsl.a" -a -d "$with_gsl/include/gsl"; then
AC_MSG_RESULT([found in $with_gsl])
GSLLIBS="-L$with_gsl/lib -R$with_gsl/lib -lgslcblas -lgsl"
GSLINCLUDE="-I$with_gsl/include"
GSLPATH="$with_gsl"
else
AC_MSG_RESULT([not found])
AC_MSG_ERROR([Can't find $with_gsl/lib/libgsl.a or the headers in $with_gsl/include])
fi
fi
AC_SUBST(GSLINCLUDE)
AC_SUBST(GSLLIBS)
AC_SUBST(GSLPATH)
])
dnl ##### COMPILERFLAGS #####
AC_DEFUN([HERWIG_COMPILERFLAGS],
[
AC_REQUIRE([HERWIG_CHECK_GSL])
AC_REQUIRE([HERWIG_CHECK_THEPEG])
AC_REQUIRE([BOOST_REQUIRE])
AC_REQUIRE([AX_COMPILER_VENDOR])
AM_CPPFLAGS="-I\$(top_builddir)/include $THEPEGINCLUDE \$(GSLINCLUDE) \$(BOOST_CPPFLAGS)"
AC_MSG_CHECKING([for debugging mode])
AC_ARG_ENABLE(debug,
AC_HELP_STRING([--enable-debug],[debug mode, use --enable-debug=slow for additional options that slow down the run.]),
[],
[enable_debug=no]
)
AC_MSG_RESULT([$enable_debug])
if test "x$enable_debug" = "xno"; then
debugflags=""
else
debugflags="-g"
fi
dnl -Wfloat-equal -fvisibility-inlines-hidden -Wctor-dtor-privacy -Weffc++
if test -n "$GCC"; then
warnflags="-pedantic -Wall -Wextra -Wno-overloaded-virtual"
if test "x$enable_debug" = "xslow"; then
debugflags="$debugflags -fno-inline"
AM_CPPFLAGS="$AM_CPPFLAGS -D_GLIBCXX_DEBUG"
fi
fi
dnl do an actual capability check on ld instead of this workaround
case "${host}" in
*-darwin*)
;;
*)
AM_LDFLAGS="-Wl,--enable-new-dtags"
;;
esac
case "${ax_cv_cxx_compiler_vendor}" in
gnu)
- AM_CXXFLAGS="-pedantic -Wall -W"
+ AM_CXXFLAGS="-pedantic -Wall -W -Wno-use-after-free"
;;
clang)
AM_CXXFLAGS="-pedantic -Wall -Wno-overloaded-virtual -Wno-unused-function -Wno-unused-parameter"
dnl -Wno-unneeded-internal-declaration
;;
intel)
AM_CXXFLAGS="-strict-ansi -Wall -wd13000,1418,981,444,383,1599,1572,2259,980"
;;
esac
AC_SUBST(AM_CPPFLAGS)
AC_SUBST(AM_CFLAGS, ["$warnflags $debugflags"])
AC_SUBST(AM_CXXFLAGS,["$AM_CXXFLAGS $warnflags $debugflags"])
AC_SUBST(AM_FCFLAGS, ["$debugflags"])
AC_SUBST(AM_LDFLAGS)
])
AC_DEFUN([HERWIG_ENABLE_MODELS],
[
AC_MSG_CHECKING([if BSM models should be built])
AC_ARG_ENABLE(models,
AC_HELP_STRING([--disable-models],[Turn off compilation of BSM models.]),
[],
[enable_models=yes]
)
AC_MSG_RESULT([$enable_models])
LOAD_BSM=""
if test "$enable_models" = "yes"; then
LOAD_BSM="read BSMlibs.in"
fi
AC_SUBST(LOAD_BSM)
AM_CONDITIONAL(WANT_BSM,[test "$enable_models" = "yes"])
])
AC_DEFUN([HERWIG_OVERVIEW],
[
FCSTRING=`$FC --version | head -1`
CXXSTRING=`$CXX --version | head -1`
CCSTRING=`$CC --version | head -1`
if test "x$PYTHON" != "x:"
then
python_was_found="yes, using Python $PYTHON_VERSION"
else
python_was_found="no, requires Python >= 2.6"
fi
cat << _HW_EOF_ > config.herwig
*****************************************************
*** $PACKAGE_STRING configuration summary
*** Please include this information in bug reports!
***--------------------------------------------------
*** Prefix: $prefix
***
*** BSM models: $enable_models
*** UFO converter: ${python_was_found}
***
*** Herwig debug mode: $enable_debug
***
*** ThePEG: $with_thepeg
*** ThePEG headers: $with_thepeg_headers
***
*** GoSam: $with_gosam
*** GoSam-Contrib: $with_gosam_contrib
*** MadGraph: $with_madgraph
*** njet: $with_njet ${NJET_VERSION}
*** OpenLoops: $with_openloops
*** VBFNLO: $with_vbfnlo
***
*** EvtGen: $with_evtgen
*** GSL: $with_gsl
*** boost: ${BOOST_CPPFLAGS:-system}
*** Fastjet: ${fjconfig}
***
*** Host: $host
*** CC: $CCSTRING
*** CXX: $CXXSTRING
*** FC: $FCSTRING
***
*** CXXFLAGS: $CXXFLAGS
*** FCFLAGS: $FCFLAGS
*****************************************************
_HW_EOF_
])

File Metadata

Mime Type
application/octet-stream
Expires
Sun, May 5, 11:40 PM (2 d)
Storage Engine
chunks
Storage Format
Chunks
Storage Handle
qMqgdQDwXXKw
Default Alt Text
(4 MB)

Event Timeline