Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F7879322
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
21 KB
Subscribers
None
View Options
diff --git a/MatrixElement/General/MEfv2fs.cc b/MatrixElement/General/MEfv2fs.cc
--- a/MatrixElement/General/MEfv2fs.cc
+++ b/MatrixElement/General/MEfv2fs.cc
@@ -1,363 +1,388 @@
// -*- C++ -*-
//
// MEfv2fs.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 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 MEfv2fs class.
//
#include "MEfv2fs.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
using namespace Herwig;
using ThePEG::Helicity::incoming;
using ThePEG::Helicity::outgoing;
void MEfv2fs::doinit() {
GeneralHardME::doinit();
scalar_.resize(numberOfDiags());
fermion_.resize(numberOfDiags());
+ vector_.resize(numberOfDiags());
initializeMatrixElements(PDT::Spin1Half, PDT::Spin1,
PDT::Spin1Half, PDT::Spin0);
for(size_t ix = 0; ix < numberOfDiags(); ++ix) {
HPDiagram curr = getProcessInfo()[ix];
if(curr.channelType == HPDiagram::tChannel) {
AbstractFFSVertexPtr ffs =
dynamic_ptr_cast<AbstractFFSVertexPtr>(curr.vertices.first);
if( curr.intermediate->iSpin() == PDT::Spin0 ) {
AbstractVSSVertexPtr vss =
dynamic_ptr_cast<AbstractVSSVertexPtr>(curr.vertices.second);
scalar_[ix] = make_pair(ffs, vss);
}
- else {
+ else if ( curr.intermediate->iSpin() == PDT::Spin1Half ) {
AbstractFFVVertexPtr ffv =
dynamic_ptr_cast<AbstractFFVVertexPtr>(curr.vertices.second);
fermion_[ix] = make_pair(ffs, ffv);
}
+ else if ( curr.intermediate->iSpin() == PDT::Spin1 ) {
+ AbstractFFVVertexPtr ffv =
+ dynamic_ptr_cast<AbstractFFVVertexPtr>(curr.vertices.first);
+ AbstractVVSVertexPtr vvs =
+ dynamic_ptr_cast<AbstractVVSVertexPtr>(curr.vertices.second);
+ vector_[ix] = make_pair(ffv, vvs);
+ }
+ else
+ assert(false);
}
else {
+ assert(curr.intermediate->iSpin() == PDT::Spin1Half );
AbstractFFVVertexPtr ffv =
dynamic_ptr_cast<AbstractFFVVertexPtr>(curr.vertices.first);
AbstractFFSVertexPtr ffs =
dynamic_ptr_cast<AbstractFFSVertexPtr>(curr.vertices.second);
fermion_[ix] = make_pair(ffs, ffv);
}
}
}
double MEfv2fs::me2() const {
//massless vector
VecWFVector vecIn(2);
ScalarWaveFunction scaOut(rescaledMomenta()[3], mePartonData()[3],
Complex(1.,0.), outgoing);
double fullme(0.);
if( mePartonData()[0]->id() > 0 ) {
SpinorVector spIn(2);
SpinorBarVector spbOut(2);
for(size_t ih = 0; ih < 2; ++ih) {
spIn[ih] = SpinorWaveFunction(rescaledMomenta()[0], mePartonData()[0], ih,
incoming);
spbOut[ih] = SpinorBarWaveFunction(rescaledMomenta()[2], mePartonData()[2], ih,
outgoing);
vecIn[ih] = VectorWaveFunction(rescaledMomenta()[1], mePartonData()[1], 2*ih,
incoming);
}
fv2fbsHeME(spIn, vecIn, spbOut, scaOut, fullme,true);
}
else {
SpinorBarVector spbIn(2);
SpinorVector spOut(2);
for(size_t ih = 0; ih < 2; ++ih) {
spbIn[ih] = SpinorBarWaveFunction(rescaledMomenta()[0], mePartonData()[0], ih,
incoming);
spOut[ih] = SpinorWaveFunction(rescaledMomenta()[2], mePartonData()[2], ih,
outgoing);
vecIn[ih] = VectorWaveFunction(rescaledMomenta()[1], mePartonData()[1], 2*ih,
incoming);
}
fbv2fsHeME(spbIn, vecIn, spOut, scaOut, fullme,true);
}
#ifndef NDEBUG
if( debugME() ) debug(fullme);
#endif
return fullme;
}
ProductionMatrixElement
MEfv2fs::fv2fbsHeME(const SpinorVector & spIn, const VecWFVector & vecIn,
const SpinorBarVector & spbOut,
const ScalarWaveFunction & scaOut,
double & me2, bool first) const {
const Energy2 q2(scale());
// weights for the selection of the diagram
vector<double> me(numberOfDiags(), 0.);
// weights for the selection of the colour flow
vector<double> flow(numberOfFlows(),0.);
me2 = 0.;
for(unsigned int ihel1 = 0; ihel1 < 2; ++ihel1) {
for(unsigned int ihel2 = 0; ihel2 < 2; ++ihel2) {
for(unsigned int ohel1 = 0; ohel1 < 2; ++ohel1) {
vector<Complex> flows(numberOfFlows(),0.);
for(size_t ix = 0; ix < numberOfDiags(); ++ix) {
Complex diag(0.);
const HPDiagram & current = getProcessInfo()[ix];
tcPDPtr offshell = current.intermediate;
if( current.channelType == HPDiagram::tChannel ) {
if( offshell->iSpin() == PDT::Spin0 ) {
ScalarWaveFunction interS = scalar_[ix].first->
evaluate(q2, 3, offshell, spIn[ihel1], spbOut[ohel1]);
diag = scalar_[ix].second->
evaluate(q2, vecIn[ihel2], scaOut, interS);
}
else if( offshell->iSpin() == PDT::Spin1Half ) {
if(offshell->CC()) offshell = offshell->CC();
SpinorBarWaveFunction interFB = fermion_[ix].second->
evaluate(q2, 3, offshell,spbOut[ohel1],vecIn[ihel2]);
diag = fermion_[ix].first->
evaluate(q2, spIn[ihel1], interFB, scaOut);
}
- else diag = 0.0;
+ else {
+ VectorWaveFunction interV = vector_[ix].first->
+ evaluate(q2,3,offshell,spIn[ihel1],spbOut[ohel1]);
+ diag = vector_[ix].second->
+ evaluate(q2, vecIn[ihel2], interV, scaOut);
+ }
}
else if( current.channelType == HPDiagram::sChannel ) {
// check if take intermediate massless
unsigned int propOpt =
abs(offshell->id()) != abs(spIn[ihel1].particle()->id()) ? 1 : 5;
SpinorWaveFunction interF = fermion_[ix].second->
evaluate(q2, propOpt, offshell, spIn[ihel1], vecIn[ihel2]);
diag = fermion_[ix].first->
evaluate(q2, interF, spbOut[ohel1], scaOut);
}
- else diag = 0.0;
+ else
+ assert(false);
me[ix] += norm(diag);
diagramME()[ix](ihel1, 2*ihel2, ohel1, 0) = diag;
//Compute flows
for(size_t iy = 0; iy < current.colourFlow.size(); ++iy) {
assert(current.colourFlow[iy].first<flows.size());
flows[current.colourFlow[iy].first] +=
current.colourFlow[iy].second * diag;
}
}
// MEs for the different colour flows
for(unsigned int iy = 0; iy < numberOfFlows(); ++iy)
flowME()[iy](ihel1, 2*ihel2, ohel1, 0) = flows[iy];
//Now add flows to me2 with appropriate colour factors
for(size_t ii = 0; ii < numberOfFlows(); ++ii)
for(size_t ij = 0; ij < numberOfFlows(); ++ij)
me2 += getColourFactors()[ii][ij]*(flows[ii]*conj(flows[ij])).real();
// contribution to the colour flow
for(unsigned int ii = 0; ii < numberOfFlows(); ++ii) {
flow[ii] += getColourFactors()[ii][ii]*norm(flows[ii]);
}
}
}
}
// if not computing the cross section return the selected colour flow
if(!first) return flowME()[colourFlow()];
me2 = selectColourFlow(flow,me,me2);
return flowME()[colourFlow()];
}
ProductionMatrixElement
MEfv2fs::fbv2fsHeME(const SpinorBarVector & spbIn, const VecWFVector & vecIn,
const SpinorVector & spOut,
const ScalarWaveFunction & scaOut,
double & me2, bool first) const {
const Energy2 q2(scale());
// weights for the selection of the diagram
vector<double> me(numberOfDiags(), 0.);
// weights for the selection of the colour flow
vector<double> flow(numberOfFlows(),0.);
me2 = 0.;
for(unsigned int ihel1 = 0; ihel1 < 2; ++ihel1) {
for(unsigned int ihel2 = 0; ihel2 < 2; ++ihel2) {
for(unsigned int ohel1 = 0; ohel1 < 2; ++ohel1) {
vector<Complex> flows(numberOfFlows(),0.);
for(HPCount ix = 0; ix < numberOfDiags(); ++ix) {
Complex diag(0.);
const HPDiagram & current = getProcessInfo()[ix];
tcPDPtr offshell = current.intermediate;
if( current.channelType == HPDiagram::tChannel ) {
if( offshell->iSpin() == PDT::Spin0 ) {
ScalarWaveFunction interS = scalar_[ix].first->
evaluate(q2, 3, offshell, spOut[ohel1], spbIn[ihel1]);
diag = scalar_[ix].second->
evaluate(q2, vecIn[ihel2], interS, scaOut);
}
else if( offshell->iSpin() == PDT::Spin1Half ) {
SpinorBarWaveFunction interFB = fermion_[ix].first->
evaluate(q2, 3, offshell, spbIn[ihel1], scaOut);
diag = fermion_[ix].second->
evaluate(q2, spOut[ohel1], interFB, vecIn[ihel2]);
}
- else diag = 0.0;
+ else if( offshell->iSpin() == PDT::Spin1 ) {
+ VectorWaveFunction interV = vector_[ix].first->
+ evaluate(q2,3,offshell, spOut[ohel1], spbIn[ihel1]);
+ diag = vector_[ix].second->
+ evaluate(q2, vecIn[ihel2], interV, scaOut);
+ }
+ else
+ assert(false);
}
else if( current.channelType == HPDiagram::sChannel ) {
// check if take intermediate massless
unsigned int propOpt =
abs(offshell->id()) != abs(spbIn[ihel1].particle()->id()) ? 1 : 5;
SpinorBarWaveFunction interFB = fermion_[ix].second->
evaluate(q2, propOpt, offshell, spbIn[ihel1], vecIn[ihel2]);
diag = fermion_[ix].first->
evaluate(q2, spOut[ohel1], interFB, scaOut);
}
- else diag = 0.0;
+ else
+ assert(false);
me[ix] += norm(diag);
diagramME()[ix](ihel1, 2*ihel2, ohel1, 0) = diag;
//Compute flows
for(size_t iy = 0; iy < current.colourFlow.size(); ++iy) {
assert(current.colourFlow[iy].first<flows.size());
flows[current.colourFlow[iy].first] +=
current.colourFlow[iy].second * diag;
}
}
// MEs for the different colour flows
for(unsigned int iy = 0; iy < numberOfFlows(); ++iy)
flowME()[iy](ihel1, 2*ihel2, ohel1, 0) = flows[iy];
//Now add flows to me2 with appropriate colour factors
for(size_t ii = 0; ii < numberOfFlows(); ++ii)
for(size_t ij = 0; ij < numberOfFlows(); ++ij)
me2 += getColourFactors()[ii][ij]*(flows[ii]*conj(flows[ij])).real();
// contribution to the colour flow
for(unsigned int ii = 0; ii < numberOfFlows(); ++ii) {
flow[ii] += getColourFactors()[ii][ii]*norm(flows[ii]);
}
}
}
}
// if not computing the cross section return the selected colour flow
if(!first) return flowME()[colourFlow()];
me2 = selectColourFlow(flow,me,me2);
return flowME()[colourFlow()];
}
void MEfv2fs::persistentOutput(PersistentOStream & os) const {
- os << scalar_ << fermion_;
+ os << scalar_ << fermion_ << vector_;
}
void MEfv2fs::persistentInput(PersistentIStream & is, int) {
- is >> scalar_ >> fermion_;
+ is >> scalar_ >> fermion_ >> vector_;
initializeMatrixElements(PDT::Spin1Half, PDT::Spin1,
PDT::Spin1Half, PDT::Spin0);
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<MEfv2fs,GeneralHardME>
describeHerwigMEfv2fs("Herwig::MEfv2fs", "Herwig.so");
void MEfv2fs::Init() {
static ClassDocumentation<MEfv2fs> documentation
("This class implements the matrix element for a fermion-vector to "
"a fermioin-scalar.");
}
void MEfv2fs::constructVertex(tSubProPtr subp) {
ParticleVector external = hardParticles(subp);
//calculate production ME
VecWFVector vecIn;
VectorWaveFunction(vecIn, external[1], incoming, false, true);
ScalarWaveFunction scaOut(external[3], outgoing, true);
//Need to use rescale momenta to calculate matrix element
setRescaledMomenta(external);
double dummy(0.);
if( external[0]->id() > 0 ) {
SpinorVector spIn;
SpinorBarVector spbOut;
SpinorWaveFunction (spIn, external[0], incoming, false);
SpinorBarWaveFunction(spbOut, external[2], outgoing, true);
SpinorWaveFunction spr (rescaledMomenta()[0],
external[0]->dataPtr(), incoming);
VectorWaveFunction vr (rescaledMomenta()[1],
external[1]->dataPtr(), incoming);
SpinorBarWaveFunction sbr (rescaledMomenta()[2],
external[2]->dataPtr(), outgoing);
scaOut = ScalarWaveFunction(rescaledMomenta()[3],
external[3]->dataPtr(), outgoing);
for( unsigned int ihel = 0; ihel < 2; ++ihel ) {
spr.reset(ihel);
spIn[ihel] = spr;
vr.reset(2*ihel);
vecIn[ihel] = vr;
sbr.reset(ihel);
spbOut[ihel] = sbr;
}
ProductionMatrixElement prodME = fv2fbsHeME(spIn, vecIn, spbOut,
scaOut, dummy,false);
createVertex(prodME,external);
}
else {
SpinorBarVector spbIn;
SpinorVector spOut;
SpinorBarWaveFunction(spbIn, external[0], incoming, false);
SpinorWaveFunction (spOut, external[2], outgoing, true);
SpinorBarWaveFunction sbr (rescaledMomenta()[0],
external[0]->dataPtr(), incoming);
VectorWaveFunction vr (rescaledMomenta()[1],
external[1]->dataPtr(), incoming);
SpinorWaveFunction spr (rescaledMomenta()[2],
external[2]->dataPtr(), outgoing);
scaOut = ScalarWaveFunction(rescaledMomenta()[3],
external[3]->dataPtr(), outgoing);
for( unsigned int ihel = 0; ihel < 2; ++ihel ) {
sbr.reset(ihel);
spbIn[ihel] = sbr;
vr.reset(2*ihel);
vecIn[ihel] = vr;
spr.reset(ihel);
spOut[ihel] = spr;
}
ProductionMatrixElement prodME = fbv2fsHeME(spbIn, vecIn, spOut,
scaOut, dummy,false);
createVertex(prodME,external);
}
#ifndef NDEBUG
if( debugME() ) debug(dummy/96.);
#endif
}
void MEfv2fs::debug(double me2) const {
if( !generator()->logfile().is_open() ) return;
long id1 = abs(mePartonData()[0]->id());
long id4 = abs(mePartonData()[3]->id());
if( (id1 != 1 && id1 != 2) || mePartonData()[1]->id() != 21 ||
mePartonData()[2]->id() != 1000021 ||
(id4 != 1000001 && id4 != 1000002 && id4 != 2000001 &&
id4 != 2000002) ) return;
tcSMPtr sm = generator()->standardModel();
double gs4 = sqr( 4.*Constants::pi*sm->alphaS(scale()) );
int Nc = sm->Nc();
Energy2 m3s = sqr(mePartonData()[2]->mass());
Energy2 m4s = sqr(mePartonData()[3]->mass());
//formula has vf->fs so swap t and u
Energy2 s(sHat()), t3(uHat() - m3s), u4(tHat() - m4s);
double analytic = -gs4*( u4 + 2.*(m4s - m3s)*(1. + m3s/t3 + m4s/u4) )*
( sqr(u4) + sqr(s) - sqr(t3)/sqr(Nc) )/s/t3/u4/4.;
double diff = abs( analytic - me2);
if( diff > 1e-4 ) {
generator()->log()
<< mePartonData()[0]->PDGName() << ","
<< mePartonData()[1]->PDGName() << "->"
<< mePartonData()[2]->PDGName() << ","
<< mePartonData()[3]->PDGName() << " difference: "
<< setprecision(10) << diff << " ratio: " << analytic/me2 << '\n';
}
}
diff --git a/MatrixElement/General/MEfv2fs.h b/MatrixElement/General/MEfv2fs.h
--- a/MatrixElement/General/MEfv2fs.h
+++ b/MatrixElement/General/MEfv2fs.h
@@ -1,205 +1,211 @@
// -*- C++ -*-
//
// MEfv2fs.h is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 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_MEfv2fs_H
#define HERWIG_MEfv2fs_H
//
// This is the declaration of the MEfv2fs class.
//
#include "GeneralHardME.h"
#include "ThePEG/Helicity/WaveFunction/SpinorWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/SpinorBarWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
#include "Herwig/MatrixElement/ProductionMatrixElement.h"
#include "ThePEG/Helicity/Vertex/AbstractFFVVertex.h"
#include "ThePEG/Helicity/Vertex/AbstractFFSVertex.h"
#include "ThePEG/Helicity/Vertex/AbstractVSSVertex.h"
+#include "ThePEG/Helicity/Vertex/AbstractVVSVertex.h"
namespace Herwig {
using namespace ThePEG;
using ThePEG::Helicity::SpinorWaveFunction;
using ThePEG::Helicity::SpinorBarWaveFunction;
using ThePEG::Helicity::VectorWaveFunction;
using ThePEG::Helicity::ScalarWaveFunction;
/**
* This class is designed to implement the matrix element for
* fermion-vector to fermion scalar. It inherits from GeneralHardME
* and implements the required virtual functions.
*
* @see @see \ref MEfv2fsInterfaces "The Interfaces"
* defined for MEfv2fs.
* @see GeneralHardME
*/
class MEfv2fs: public GeneralHardME {
/** Vector of SpinorWaveFunctions. */
typedef vector<SpinorWaveFunction> SpinorVector;
/** Vector of SpinorBarWaveFunctions. */
typedef vector<SpinorBarWaveFunction> SpinorBarVector;
/** Vector of VectorWaveFunctions. */
typedef vector<VectorWaveFunction> VecWFVector;
public:
/**
* The default constructor.
*/
- MEfv2fs() : scalar_(0), fermion_(0) {}
+ MEfv2fs() : scalar_(0), fermion_(0), vector_(0) {}
public:
/** @name Virtual functions required by the GeneralHardME class. */
//@{
/**
* 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;
//@}
/**
* Construct the vertex information for the spin correlations
* @param subp Pointer to the relevent SubProcess
*/
virtual void constructVertex(tSubProPtr subp);
private:
/** @name Functions to calculate production matrix elements and me2. */
//@{
/**
* Calculate me2 and the production matrix element for the normal mode.
* @param spIn Vector of SpinorWaveFunction for the incoming fermion
* @param vecIn Vector of VectorWaveFunction for incoming boson
* @param spbOut Vector of SpinorBarWaveFunction for outgoing fermion
* @param scaOut ScalarWaveFunction for outgoing scalar.
* @param first Whether or not first call to decide if colour decomposition etc
* should be calculated
* @param full_me The value of me2 calculation
*/
ProductionMatrixElement fv2fbsHeME(const SpinorVector & spIn,
const VecWFVector & vecIn,
const SpinorBarVector & spbOut,
const ScalarWaveFunction & scaOut,
double & full_me, bool first) const;
/**
* Calculate me2 and the production matrix element for the cc mode.
* @param spbIn Vector of SpinorBarWaveFunction for the incoming fermion
* @param vecIn Vector of VectorWaveFunction for incoming boson
* @param spOut Vector of SpinorWaveFunction for outgoing fermion
* @param scaOut ScalarWaveFunction for outgoing scalar.
* @param first Whether or not first call to decide if colour decomposition etc
* should be calculated
* @param full_me The value of me2 calculation
*/
ProductionMatrixElement fbv2fsHeME(const SpinorBarVector & spbIn,
const VecWFVector & vecIn,
const SpinorVector & spOut,
const ScalarWaveFunction & scaOut,
double & full_me, bool first) const;
//@}
protected:
/**
* A debugging function to test the value of me2 against an
* analytic function.
* @param me2 The value of the \f$ |\bar{\mathcal{M}}|^2 \f$
*/
virtual void debug(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 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.
*/
void doinit();
//@}
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);}
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
MEfv2fs & operator=(const MEfv2fs &);
private:
/**
* Store a pair of FFSVertex and VSSVertex pointers
*/
vector<pair<AbstractFFSVertexPtr, AbstractVSSVertexPtr> > scalar_;
/**
* Store a pair of FFSVertex and FFVVertex pointers
*/
vector<pair<AbstractFFSVertexPtr, AbstractFFVVertexPtr> > fermion_;
+
+ /**
+ * Store a pair of VVSVertex and FFVVertex pointers
+ */
+ vector<pair<AbstractFFVVertexPtr,AbstractVVSVertexPtr> > vector_;
};
}
#endif /* HERWIG_MEfv2fs_H */
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Nov 19, 7:57 PM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3805941
Default Alt Text
(21 KB)
Attached To
R563 testingHerwigHG
Event Timeline
Log In to Comment