Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F10881028
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Subscribers
None
View Options
diff --git a/Models/General/ResonantProcessConstructor.cc b/Models/General/ResonantProcessConstructor.cc
--- a/Models/General/ResonantProcessConstructor.cc
+++ b/Models/General/ResonantProcessConstructor.cc
@@ -1,390 +1,412 @@
// -*- C++ -*-
//
// ResonantProcessConstructor.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 ResonantProcessConstructor class.
//
#include "ResonantProcessConstructor.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Interface/RefVector.h"
#include "ThePEG/Interface/Parameter.h"
#include "ThePEG/Interface/Switch.h"
using namespace Herwig;
IBPtr ResonantProcessConstructor::clone() const {
return new_ptr(*this);
}
IBPtr ResonantProcessConstructor::fullclone() const {
return new_ptr(*this);
}
void ResonantProcessConstructor::persistentOutput(PersistentOStream & os) const {
- os << incoming_ << intermediates_ << outgoing_
+ os << incoming_ << intermediates_ << outgoing_
<< processOption_ << scaleChoice_ << scaleFactor_;
}
void ResonantProcessConstructor::persistentInput(PersistentIStream & is, int) {
- is >> incoming_ >> intermediates_ >> outgoing_
+ is >> incoming_ >> intermediates_ >> outgoing_
>> processOption_ >> scaleChoice_ >> scaleFactor_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<ResonantProcessConstructor,HardProcessConstructor>
describeHerwigResonantProcessConstructor("Herwig::ResonantProcessConstructor", "Herwig.so");
void ResonantProcessConstructor::Init() {
static ClassDocumentation<ResonantProcessConstructor> documentation
("This class is designed solely to contruct resonant processes using"
"a provided set of intermediate particles");
-
+
static RefVector<ResonantProcessConstructor, ParticleData> interfaceOffshell
("Intermediates",
"A vector of offshell particles for resonant diagrams",
- &ResonantProcessConstructor::intermediates_, -1, false, false, true,
+ &ResonantProcessConstructor::intermediates_, -1, false, false, true,
false);
static RefVector<ResonantProcessConstructor, ParticleData> interfaceIncoming
("Incoming",
"A vector of incoming particles for resonant diagrams",
- &ResonantProcessConstructor::incoming_, -1, false, false, true,
+ &ResonantProcessConstructor::incoming_, -1, false, false, true,
false);
static RefVector<ResonantProcessConstructor, ParticleData> interfaceOutgoing
("Outgoing",
"A vector of outgoing particles for resonant diagrams",
- &ResonantProcessConstructor::outgoing_, -1, false, false, true,
+ &ResonantProcessConstructor::outgoing_, -1, false, false, true,
false);
static Switch<ResonantProcessConstructor,unsigned int> interfaceProcesses
("Processes",
"Whether to generate inclusive or exclusive processes",
&ResonantProcessConstructor::processOption_, 0, false, false);
static SwitchOption interfaceProcessesSingleParticleInclusive
(interfaceProcesses,
"SingleParticleInclusive",
"Require at least one particle from the list of outgoing particles"
" in the hard process",
0);
static SwitchOption interfaceProcessesTwoParticleInclusive
(interfaceProcesses,
"TwoParticleInclusive",
"Require that both the particles in the hard processes are in the"
" list of outgoing particles",
1);
static SwitchOption interfaceProcessesExclusive
(interfaceProcesses,
"Exclusive",
"Require that both the particles in the hard processes are in the"
" list of outgoing particles in every hard process",
2);
static SwitchOption interfaceProcessesInclusive
(interfaceProcesses,
"Inclusive",
"Generate all modes which are allowed for the on-shell intermediate particle",
3);
static SwitchOption interfaceProcessesVeryExclusive
(interfaceProcesses,
"VeryExclusive",
"Require that both the incoming and outgoing particles in the hard processes are in the"
" list of outgoing particles in every hard process",
4);
static Switch<ResonantProcessConstructor,unsigned int> interfaceScaleChoice
("ScaleChoice",
"&ResonantProcessConstructor::scaleChoice_",
&ResonantProcessConstructor::scaleChoice_, 1, false, false);
static SwitchOption interfaceScaleChoicesHat
(interfaceScaleChoice,
"sHat",
"Always use sHat",
1);
static SwitchOption interfaceScaleChoiceTransverseMass
(interfaceScaleChoice,
"TransverseMass",
"Always use the transverse mass",
2);
static SwitchOption interfaceScaleChoiceGeometicMean
(interfaceScaleChoice,
"MaxMT",
"Use the maximum of m^2+p_T^2 for the two particles",
3);
static Parameter<ResonantProcessConstructor,double> interfaceScaleFactor
("ScaleFactor",
"The prefactor used in the scale calculation. The scale used is"
" sHat multiplied by this prefactor",
&ResonantProcessConstructor::scaleFactor_, 1.0, 0.0, 10.0,
false, false, Interface::limited);
}
void ResonantProcessConstructor::doinit() {
HardProcessConstructor::doinit();
if((processOption_==2 || processOption_==4) &&
outgoing_.size()!=2)
- throw InitException()
+ throw InitException()
<< "Exclusive processes require exactly"
<< " two outgoing particles but " << outgoing_.size()
<< "have been inserted in ResonantProcessConstructor::doinit()."
<< Exception::runerror;
if(processOption_==4 && incoming_.size()!=2)
- throw InitException()
+ throw InitException()
<< "Exclusive processes require exactly"
<< " two incoming particles but " << incoming_.size()
<< "have been inserted in ResonantProcessConstructor::doinit()."
<< Exception::runerror;
}
void ResonantProcessConstructor::constructDiagrams() {
size_t ninc = incoming_.size() , ninter = intermediates_.size();
if(ninc == 0 || ninter == 0 || !subProcess() ) return;
// find the incoming particle pairs
vector<tPDPair> incPairs;
for(PDVector::size_type i = 0; i < ninc; ++i) {
for(PDVector::size_type j = 0; j < ninc; ++j) {
tPDPair inc = make_pair(incoming_[i], incoming_[j]);
if( (inc.first->iSpin() > inc.second->iSpin()) ||
(inc.first->iSpin() == inc.second->iSpin() &&
inc.first->id() < inc.second->id()) )
swap(inc.first, inc.second);
if( !HPC_helper::duplicateIncoming(inc,incPairs) ) {
incPairs.push_back(inc);
}
}
}
- size_t nvertices = model()->numberOfVertices();
+ size_t nvertices = model()->numberOfVertices();
//To construct resonant diagrams loop over the incoming particles, intermediates
- //and vertices to find allowed diagrams. Need to exclude the diagrams that have
+ //and vertices to find allowed diagrams. Need to exclude the diagrams that have
//the intermediate as an external particle as well
for(vector<tcPDPair>::size_type is = 0; is < incPairs.size(); ++is) {
- tPDPair ppi = incPairs[is];
+ tPDPair ppi = incPairs[is];
for(vector<PDPtr>::size_type ik = 0; ik < ninter ; ++ik) {
long ipart = intermediates_[ik]->id();
for(size_t iv = 0; iv < nvertices; ++iv) {
VBPtr vertex = model()->vertex(iv);
if(vertex->getNpoint() > 3) continue;
long part1 = ppi.first->CC() ? -ppi.first->id() : ppi.first->id();
long part2 = ppi.second->CC() ? -ppi.second->id() : ppi.second->id();
- if(vertex->allowed(part1, part2, ipart) ||
+ if(vertex->allowed(part1, part2, ipart) ||
vertex->allowed(part1, ipart, part2) ||
vertex->allowed(part2, part1, ipart) ||
vertex->allowed(part2, ipart, part1) ||
vertex->allowed(ipart, part1, part2) ||
vertex->allowed(ipart, part2, part1) ) {
- constructVertex2(make_pair(ppi.first->id(), ppi.second->id()), vertex,
+ constructVertex2(make_pair(ppi.first->id(), ppi.second->id()), vertex,
intermediates_[ik]);
}
}
}
}
//Create matrix element for each process
const HPDVector::size_type ndiags = diagrams_.size();
- for(HPDVector::size_type ix = 0; ix < ndiags; ++ix)
- createMatrixElement(diagrams_[ix]);
+ vector<string> diagLib;
+ for(HPDVector::size_type ix = 0; ix < ndiags; ++ix) {
+ vector<tcPDPtr> extpart(4);
+ extpart[0] = getParticleData(diagrams_[ix].incoming.first);
+ extpart[1] = getParticleData(diagrams_[ix].incoming.second);
+ extpart[2] = getParticleData(diagrams_[ix].outgoing.first);
+ extpart[3] = getParticleData(diagrams_[ix].outgoing.second);
+ string objectname("");
+ string classname = MEClassname(extpart, diagrams_[ix].intermediate, objectname);
+ if(std::find(diagLib.begin(), diagLib.end(), objectname) == diagLib.end()) {
+ createMatrixElement(diagrams_[ix]);
+ diagLib.push_back(objectname);
+ }
+ else {
+ cerr<<"Warning: ResonantProcessConstructor::constructDiagrams - "
+ <<"UFO model tried to produce douplicate diagrams for "
+ << extpart[0]->PDGName() << " " << extpart[1]->PDGName() << "->"
+ << extpart[2]->PDGName() << " " << extpart[3]->PDGName() << " "
+ << "for the class: \"" << classname <<" "
+ << "in object " << objectname << "\". "
+ <<"neglectiting douplicat diagram.\n";
+ continue;
+ }
+ }
}
void ResonantProcessConstructor::
-constructVertex2(IDPair in, VertexBasePtr vertex,
+constructVertex2(IDPair in, VertexBasePtr vertex,
PDPtr partc) {
//We have the left hand part of the diagram, just need all the possibilities
//for the RHS
- size_t nvertices = model()->numberOfVertices();
+ size_t nvertices = model()->numberOfVertices();
if(processOption_!=3) {
for(size_t io = 0; io < outgoing_.size(); ++io) {
tcPDPtr outa = outgoing_[io];
for(size_t iv = 0; iv < nvertices; ++iv) {
VBPtr vertex2 = model()->vertex(iv);
if(vertex2->getNpoint() > 3) continue;
- tPDSet outb = search(vertex2, partc->id(), incoming, outa->id(), outgoing,
+ tPDSet outb = search(vertex2, partc->id(), incoming, outa->id(), outgoing,
outgoing);
for(tPDSet::const_iterator ita = outb.begin(); ita != outb.end(); ++ita)
- makeResonantDiagram(in, partc, outa->id(),(**ita).id(),
+ makeResonantDiagram(in, partc, outa->id(),(**ita).id(),
make_pair(vertex, vertex2));
}
}
}
else {
long idRes = !partc->CC() ? partc->id() : partc->CC()->id();
for(size_t iv = 0; iv < nvertices; ++iv) {
VBPtr vertex2 = model()->vertex(iv);
if(vertex2->getNpoint() > 3) continue;
for(unsigned int ix = 0;ix < 3; ++ix) {
vector<long> pdlist = vertex2->search(ix, idRes);
for(unsigned int iy=0;iy<pdlist.size();iy+=3) {
long out1 = ix==0 ? pdlist.at(iy+1) : pdlist.at(iy );
long out2 = ix==2 ? pdlist.at(iy+1) : pdlist.at(iy+2);
- if(partc->mass() < getParticleData(out1)->mass() +
+ if(partc->mass() < getParticleData(out1)->mass() +
getParticleData(out2)->mass()) continue;
- makeResonantDiagram(in, partc, out1, out2,
+ makeResonantDiagram(in, partc, out1, out2,
make_pair(vertex, vertex2));
}
}
}
}
}
void ResonantProcessConstructor::
-makeResonantDiagram(IDPair in, PDPtr offshell, long outa, long outb,
+makeResonantDiagram(IDPair in, PDPtr offshell, long outa, long outb,
VBPair vertpair) {
assert(vertpair.first && vertpair.second);
- if( abs(outa) == abs(offshell->id()) ||
+ if( abs(outa) == abs(offshell->id()) ||
abs(outb) == abs(offshell->id())) return;
HPDiagram newdiag(in,make_pair(outa,outb));
newdiag.intermediate = offshell;
newdiag.vertices = vertpair;
newdiag.channelType = HPDiagram::sChannel;
fixFSOrder(newdiag);
assignToCF(newdiag);
if(duplicate(newdiag,diagrams_)) return;
// if inclusive enforce the exclusivity
if(processOption_==1) {
- PDVector::const_iterator loc =
+ PDVector::const_iterator loc =
std::find(outgoing_.begin(),outgoing_.end(),
getParticleData(newdiag.outgoing. first));
if(loc==outgoing_.end()) return;
- loc =
+ loc =
std::find(outgoing_.begin(),outgoing_.end(),
getParticleData(newdiag.outgoing.second));
if(loc==outgoing_.end()) return;
}
else if(processOption_==2 || processOption_==4 ) {
if(!((newdiag.outgoing. first==outgoing_[0]->id()&&
newdiag.outgoing.second==outgoing_[1]->id())||
(newdiag.outgoing. first==outgoing_[1]->id()&&
newdiag.outgoing.second==outgoing_[0]->id())))
return;
if(processOption_==4) {
if(!((newdiag.incoming. first==incoming_[0]->id()&&
newdiag.incoming.second==incoming_[1]->id())||
(newdiag.incoming. first==incoming_[1]->id()&&
newdiag.incoming.second==incoming_[0]->id())))
return;
}
}
// add to the list
if(checkOrder(newdiag)) diagrams_.push_back(newdiag);
}
-
-set<tPDPtr>
-ResonantProcessConstructor::search(VBPtr vertex, long part1, direction d1,
+
+set<tPDPtr>
+ResonantProcessConstructor::search(VBPtr vertex, long part1, direction d1,
long part2, direction d2, direction d3) {
if(d1 == incoming && getParticleData(part1)->CC()) part1 = -part1;
if(d2 == incoming && getParticleData(part2)->CC()) part2 = -part2;
vector<long> ext;
tPDSet third;
for(unsigned int ix = 0;ix < 3; ++ix) {
vector<long> pdlist = vertex->search(ix, part1);
ext.insert(ext.end(), pdlist.begin(), pdlist.end());
}
for(unsigned int ix = 0; ix < ext.size(); ix += 3) {
long id0 = ext.at(ix);
long id1 = ext.at(ix+1);
long id2 = ext.at(ix+2);
int pos;
if((id0 == part1 && id1 == part2) ||
(id0 == part2 && id1 == part1))
pos = ix + 2;
else if((id0 == part1 && id2 == part2) ||
(id0 == part2 && id2 == part1))
pos = ix + 1;
else if((id1 == part1 && id2 == part2) ||
(id1 == part2 && id2 == part1))
pos = ix;
else
pos = -1;
if(pos >= 0) {
tPDPtr p = getParticleData(ext[pos]);
if(d3 == incoming && p->CC()) p = p->CC();
third.insert(p);
}
}
-
+
return third;
}
-
+
IDPair ResonantProcessConstructor::
find(long part, const vector<PDPtr> & out) const {
vector<PDPtr>::size_type iloc(0);
bool found(false);
do {
if(out[iloc]->id() == part) found = true;
else ++iloc;
}
while(found == false && iloc < out.size());
//found offshell
IDPair outids;
if(iloc == 0)
outids = make_pair(out[1]->id(), out[2]->id());
else if(iloc == 1)
outids = make_pair(out[0]->id(), out[2]->id());
else
outids = make_pair(out[0]->id(), out[1]->id());
return outids;
-}
+}
void ResonantProcessConstructor::
createMatrixElement(const HPDiagram & diag) const {
vector<tcPDPtr> extpart(4);
extpart[0] = getParticleData(diag.incoming.first);
extpart[1] = getParticleData(diag.incoming.second);
extpart[2] = getParticleData(diag.outgoing.first);
extpart[3] = getParticleData(diag.outgoing.second);
string objectname ("/Herwig/MatrixElements/");
string classname = MEClassname(extpart, diag.intermediate, objectname);
GeneralHardMEPtr matrixElement = dynamic_ptr_cast<GeneralHardMEPtr>
(generator()->preinitCreate(classname, objectname));
if( !matrixElement ) {
- throw RPConstructorError()
+ throw RPConstructorError()
<< "ResonantProcessConstructor::createMatrixElement "
<< "- No matrix element object could be created for "
- << "the process "
- << extpart[0]->PDGName() << " " << extpart[0]->iSpin() << ","
- << extpart[1]->PDGName() << " " << extpart[1]->iSpin() << "->"
- << extpart[2]->PDGName() << " " << extpart[2]->iSpin() << ","
- << extpart[3]->PDGName() << " " << extpart[3]->iSpin()
+ << "the process "
+ << extpart[0]->PDGName() << " " << extpart[0]->iSpin() << ","
+ << extpart[1]->PDGName() << " " << extpart[1]->iSpin() << "->"
+ << extpart[2]->PDGName() << " " << extpart[2]->iSpin() << ","
+ << extpart[3]->PDGName() << " " << extpart[3]->iSpin()
<< ". Constructed class name: \"" << classname << "\"\n"
<< Exception::warning;
return;
}
matrixElement->setProcessInfo(HPDVector(1, diag),
colourFlow(extpart), debug(),scaleChoice_-1,scaleFactor_);
- generator()->preinitInterface(subProcess(), "MatrixElements",
+ generator()->preinitInterface(subProcess(), "MatrixElements",
subProcess()->MEs().size(),
- "insert", matrixElement->fullName());
+ "insert", matrixElement->fullName());
}
string ResonantProcessConstructor::
MEClassname(const vector<tcPDPtr> & extpart, tcPDPtr inter,
string & objname) const {
string classname("Herwig::ME");
for(vector<tcPDPtr>::size_type ix = 0; ix < extpart.size(); ++ix) {
if(ix == 2) classname += "2";
if(extpart[ix]->iSpin() == PDT::Spin0) classname += "s";
else if(extpart[ix]->iSpin() == PDT::Spin1) classname += "v";
else if(extpart[ix]->iSpin() == PDT::Spin1Half) classname += "f";
else if(extpart[ix]->iSpin() == PDT::Spin2) classname += "t";
else
throw RPConstructorError()
<< "MEClassname() : Encountered an unknown spin for "
<< extpart[ix]->PDGName() << " while constructing MatrixElement "
<< "classname " << extpart[ix]->iSpin() << Exception::warning;
}
objname += "ME" + extpart[0]->PDGName() + extpart[1]->PDGName() + "2"
+ inter->PDGName() + "2"
+ extpart[2]->PDGName() + extpart[3]->PDGName();
- return classname;
+ return classname;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, May 3, 5:46 AM (5 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4879928
Default Alt Text
(17 KB)
Attached To
rHERWIGHG herwighg
Event Timeline
Log In to Comment