herwig is hosted by Hepforge, IPPP Durham
Herwig 7.3.0
PrototypeVertex.h
1// -*- C++ -*-
2//
3// PrototypeVertex.h is a part of Herwig - A multi-purpose Monte Carlo event generator
4// Copyright (C) 2002-2019 The Herwig Collaboration
5//
6// Herwig is licenced under version 3 of the GPL, see COPYING for details.
7// Please respect the MCnet academic guidelines, see GUIDELINES for details.
8//
9#ifndef HERWIG_PrototypeVertex_H
10#define HERWIG_PrototypeVertex_H
11#include <stack>
12#include "ThePEG/Helicity/Vertex/VertexBase.h"
13#include "ThePEG/Persistency/PersistentOStream.h"
14#include "ThePEG/Persistency/PersistentIStream.h"
15#include "ThePEG/Utilities/EnumIO.h"
16#include "NBodyDecayConstructorBase.fh"
17//
18// This is the declaration of the PrototypeVertex class.
19//
20
21namespace Herwig {
22using namespace ThePEG;
23using Helicity::VertexBasePtr;
24
25class PrototypeVertex;
26ThePEG_DECLARE_POINTERS(Herwig::PrototypeVertex,PrototypeVertexPtr);
27
29typedef pair<unsigned int, double> CFPair;
30
31
41 bool operator() (tcPDPtr p1, tcPDPtr p2) const {
42 return abs(p1->id()) > abs(p2->id()) ||
43 ( abs(p1->id()) == abs(p2->id()) && p1->id() > p2->id() ) ||
44 ( p1->id() == p2->id() && p1->fullName() > p2->fullName() );
45 }
46};
47
57 bool operator() (const pair< tPDPtr, PrototypeVertexPtr > & p1,
58 const pair< tPDPtr, PrototypeVertexPtr > & p2) const {
59 return abs(p1.first->id()) > abs(p2.first->id()) ||
60 ( abs(p1.first->id()) == abs(p2.first->id()) && p1.first->id() > p2.first->id() ) ||
61 ( p1.first->id() == p2.first->id() && p1.first->fullName() > p2.first->fullName() );
62 }
63};
64
65typedef multiset<pair< tPDPtr, PrototypeVertexPtr >,VertexOrdering > OrderedVertices;
66
70typedef multiset<PDPtr,ParticleOrdering> OrderedParticles;
71
75class PrototypeVertex : public Base {
76
77public:
78
83
87 PrototypeVertex(tPDPtr in, OrderedVertices out,
88 VertexBasePtr v, int n) :
89 incoming(in), outgoing(out), vertex(v), npart(n),
90 possibleOnShell(false) {}
91
96
100 OrderedVertices outgoing;
101
105 VertexBasePtr vertex;
106
110 tPrototypeVertexPtr parent;
111
115 unsigned int npart;
116
121
126
130 void incrementN(int in) {
131 npart += in;
132 if(parent) parent->incrementN(in);
133 }
134
138 Energy incomingMass() {
139 return incoming->mass();
140 }
141
145 Energy outgoingMass() {
146 Energy mass(ZERO);
147 for(OrderedVertices::const_iterator it = outgoing.begin();
148 it!=outgoing.end();++it) {
149 mass += it->second ?
150 it->second->outgoingMass() : it->first->mass();
151 }
152 return mass;
153 }
154
159 Energy mass(ZERO);
160 for(OrderedVertices::const_iterator it = outgoing.begin();
161 it!=outgoing.end();++it) {
162 mass += it->second ?
163 it->second->outgoingConstituentMass() : it->first->constituentMass();
164 }
165 return mass;
166 }
167
171 bool checkExternal(bool first=true) {
172 if(outPart.empty()) setOutgoing();
173 if(first&&outPart.find(incoming)!=outPart.end()) return false;
174 bool output = true;
175 for(OrderedVertices::const_iterator it = outgoing.begin();
176 it!=outgoing.end();++it) {
177 if(it->second&& !it->second->checkExternal(false)) output = false;
178 }
179 return output;
180 }
181
185 void setOutgoing() const {
186 assert(outPart.empty());
187 for(OrderedVertices::const_iterator it = outgoing.begin();
188 it!=outgoing.end();++it) {
189 if(it->second) {
190 it->second->setOutgoing();
191 outPart.insert(it->second->outPart.begin(),
192 it->second->outPart.end());
193 }
194 else
195 outPart.insert(it->first);
196 }
197 }
198
202 bool canBeOnShell(unsigned int opt,Energy maxMass,bool first);
203
207 bool sameDecay(const PrototypeVertex & x) const;
208
212 static void createPrototypes(tPDPtr inpart, VertexBasePtr vertex,
213 std::stack<PrototypeVertexPtr> & prototypes,
214 NBodyDecayConstructorBasePtr decayCon);
215
219 static void expandPrototypes(PrototypeVertexPtr proto, VertexBasePtr vertex,
220 std::stack<PrototypeVertexPtr> & prototypes,
221 const set<PDPtr> & excluded,
222 NBodyDecayConstructorBasePtr decayCon);
223
227 static PrototypeVertexPtr replicateTree(PrototypeVertexPtr parent,
228 PrototypeVertexPtr oldChild,
229 PrototypeVertexPtr & newChild);
230
231};
232
236inline ostream & operator<<(ostream & os, const PrototypeVertex & diag) {
237 os << diag.incoming->PDGName() << " -> ";
238 bool seq=false;
239 for(OrderedVertices::const_iterator it = diag.outgoing.begin();
240 it!=diag.outgoing.end();++it) {
241 os << it->first->PDGName() << " ";
242 if(it->second) seq = true;
243 }
244 os << " decays via "
245 << diag.vertex->fullName() << " in a "
246 << diag.npart << "-body decay\n";
247 if(!seq) return os;
248 os << "Followed by\n";
249 for(OrderedVertices::const_iterator it = diag.outgoing.begin();
250 it!=diag.outgoing.end();++it) {
251 if(it->second) os << *it->second;
252 }
253 return os;
254}
255
259inline bool operator==(const PrototypeVertex & x, const PrototypeVertex & y) {
260 if(x.incoming != y.incoming) return false;
261 if(x.vertex != y.vertex) return false;
262 if(x.npart != y.npart) return false;
263 if(x.outgoing.empty()&&y.outgoing.empty()) return true;
264 if(x.outgoing.size() != y.outgoing.size()) return false;
265 OrderedVertices::const_iterator xt = x.outgoing.begin();
266 OrderedVertices::const_iterator yt = y.outgoing.begin();
267 while(xt!=x.outgoing.end()) {
268 if(xt->first != yt->first) return false;
269 // special for identical particles
270 OrderedVertices::const_iterator lxt = x.outgoing.lower_bound(*xt);
271 OrderedVertices::const_iterator uxt = x.outgoing.upper_bound(*xt);
272 --uxt;
273 // just one particle
274 if(lxt==uxt) {
275 if(xt->second && yt->second) {
276 if(*(xt->second)==*(yt->second)) {
277 ++xt;
278 ++yt;
279 continue;
280 }
281 else return false;
282 }
283 else if(xt->second || yt->second)
284 return false;
285 ++xt;
286 ++yt;
287 }
288 // identical particles
289 else {
290 ++uxt;
291 OrderedVertices::const_iterator lyt = y.outgoing.lower_bound(*xt);
292 OrderedVertices::const_iterator uyt = y.outgoing.upper_bound(*xt);
293 unsigned int nx=0;
294 for(OrderedVertices::const_iterator ixt=lxt;ixt!=uxt;++ixt) {++nx;}
295 unsigned int ny=0;
296 for(OrderedVertices::const_iterator iyt=lyt;iyt!=uyt;++iyt) {++ny;}
297 if(nx!=ny) return false;
298 vector<bool> matched(ny,false);
299 for(OrderedVertices::const_iterator ixt=lxt;ixt!=uxt;++ixt) {
300 bool found = false;
301 unsigned int iy=0;
302 for(OrderedVertices::const_iterator iyt=lyt;iyt!=uyt;++iyt) {
303 if(matched[iy]) {
304 ++iy;
305 continue;
306 }
307 if( (!ixt->second &&!iyt->second) ||
308 ( ixt->second&&iyt->second &&
309 *(ixt->second)==*(iyt->second)) ) {
310 matched[iy] = true;
311 found = true;
312 break;
313 }
314 ++iy;
315 }
316 if(!found) return false;
317 }
318 xt=uxt;
319 yt=uyt;
320 }
321 }
322 return true;
323}
324
328struct NBVertex {
329
333 NBVertex(PrototypeVertexPtr proto = PrototypeVertexPtr() );
334
339
344
348 list<pair<PDPtr,NBVertex> > vertices;
349
353 VertexBasePtr vertex;
354};
355
360 struct NBDiagram : public NBVertex {
361
364 NBDiagram(PrototypeVertexPtr proto=PrototypeVertexPtr());
365
369 vector<unsigned int> channelType;
370
372 mutable vector<CFPair> colourFlow;
373
375 mutable vector<CFPair> largeNcColourFlow;
376};
377
384 const NBVertex & x) {
385 os << x.incoming << x.outgoing << x.vertices << x.vertex;
386 return os;
387}
388
395 NBVertex & x) {
396 is >> x.incoming >> x.outgoing >> x.vertices >> x.vertex;
397 return is;
398}
399
406 const NBDiagram & x) {
407 os << x.incoming << x.channelType << x.outgoing << x.vertices << x.vertex
409 return os;
410}
411
418 NBDiagram & x) {
419 is >> x.incoming >> x.channelType >> x.outgoing >> x.vertices >> x.vertex
421 return is;
422}
423
427inline ostream & operator<<(ostream & os, const NBVertex & vertex) {
428 os << vertex.incoming->PDGName() << " -> ";
429 bool seq=false;
430 for(list<pair<PDPtr,NBVertex> >::const_iterator it=vertex.vertices.begin();
431 it!=vertex.vertices.end();++it) {
432 os << it->first->PDGName() << " ";
433 if(it->second.incoming) seq = true;
434 }
435 os << "via vertex " << vertex.vertex->fullName() << "\n";
436 if(!seq) return os;
437 os << "Followed by\n";
438 for(list<pair<PDPtr,NBVertex> >::const_iterator it=vertex.vertices.begin();
439 it!=vertex.vertices.end();++it) {
440 if(it->second.incoming) os << it->second;
441 }
442 return os;
443}
444
448inline ostream & operator<<(ostream & os, const NBDiagram & diag) {
449 os << diag.incoming->PDGName() << " -> ";
450 for(OrderedParticles::const_iterator it=diag.outgoing.begin();
451 it!=diag.outgoing.end();++it) {
452 os << (**it).PDGName() << " ";
453 }
454 os << " has order ";
455 for(unsigned int ix=0;ix<diag.channelType.size();++ix)
456 os << diag.channelType[ix] << " ";
457 os << "\n";
458 os << "First decay " << diag.incoming->PDGName() << " -> ";
459 bool seq=false;
460 for(list<pair<PDPtr,NBVertex> >::const_iterator it=diag.vertices.begin();
461 it!=diag.vertices.end();++it) {
462 os << it->first->PDGName() << " ";
463 if(it->second.incoming) seq = true;
464 }
465 os << "via vertex " << diag.vertex->fullName() << "\n";
466 if(!seq) return os;
467 os << "Followed by\n";
468 for(list<pair<PDPtr,NBVertex> >::const_iterator it=diag.vertices.begin();
469 it!=diag.vertices.end();++it) {
470 if(it->second.incoming) os << it->second;
471 }
472 return os;
473}
474
475}
476
477#endif /* HERWIG_PrototypeVertex_H */
Storage of a potenital n-body decay.
bool checkExternal(bool first=true)
Check the external particles.
bool possibleOnShell
Can have on-shell intermediates.
Energy outgoingConstituentMass()
Total constituent mass of all the outgoing particles.
void setOutgoing() const
Set the outgoing particles.
PrototypeVertex(tPDPtr in, OrderedVertices out, VertexBasePtr v, int n)
Constructor.
static void createPrototypes(tPDPtr inpart, VertexBasePtr vertex, std::stack< PrototypeVertexPtr > &prototypes, NBodyDecayConstructorBasePtr decayCon)
Create a prototype.
VertexBasePtr vertex
The vertex for the interaction.
static void expandPrototypes(PrototypeVertexPtr proto, VertexBasePtr vertex, std::stack< PrototypeVertexPtr > &prototypes, const set< PDPtr > &excluded, NBodyDecayConstructorBasePtr decayCon)
Expand the prototypes by adding more legs.
unsigned int npart
Number of particles.
bool sameDecay(const PrototypeVertex &x) const
Check if same external particles.
Energy incomingMass()
Mass of the incoming particle.
static PrototypeVertexPtr replicateTree(PrototypeVertexPtr parent, PrototypeVertexPtr oldChild, PrototypeVertexPtr &newChild)
Copy the whole structure with a new branching.
PrototypeVertex()
Default Constructor.
tPDPtr incoming
Incoming particle.
OrderedParticles outPart
Outgoing particles.
bool canBeOnShell(unsigned int opt, Energy maxMass, bool first)
Are there potential on-shell intermediates?
void incrementN(int in)
Increment the number of particles.
Energy outgoingMass()
Total mass of all the outgoing particles.
OrderedVertices outgoing
Outgoing particles.
tPrototypeVertexPtr parent
The parent of the vertex.
-*- C++ -*-
pair< unsigned int, double > CFPair
Pair of int,double.
Definition: HPDiagram.h:36
multiset< PDPtr, ParticleOrdering > OrderedParticles
A set of ParticleData objects ordered as for the DecayMode's.
ThePEG::Ptr< ParticleData >::transient_pointer tPDPtr
PersistentIStream & operator>>(PersistentIStream &is, HandlerGroup< HDLR > &hg)
bool operator==(const LorentzVector< Value > &a, const LorentzVector< Value > &b)
constexpr ZeroUnit ZERO
ThePEG::Ptr< ParticleData >::transient_const_pointer tcPDPtr
ostream & operator<<(ostream &, const Collision &)
The NBDiagram struct contains information about a decay that has been automatically generated.
vector< CFPair > colourFlow
Store colour flow at information.
vector< unsigned int > channelType
The type of channel.
vector< CFPair > largeNcColourFlow
Store colour flow at information.
NBDiagram(PrototypeVertexPtr proto=PrototypeVertexPtr())
Constructor taking a prototype vertex as the arguments.
A simple vertex for the N-body diagram.
OrderedParticles outgoing
Outgoing particles.
NBVertex(PrototypeVertexPtr proto=PrototypeVertexPtr())
Constructor taking a prototype vertex as the arguments.
VertexBasePtr vertex
The vertex.
tPDPtr incoming
Incoming particle.
list< pair< PDPtr, NBVertex > > vertices
The vertices.
A struct to order the particles in the same way as in the DecayModes.
bool operator()(tcPDPtr p1, tcPDPtr p2) const
Operator for the ordering.
A struct to order the particles in the same way as in the DecayMode's.
bool operator()(const pair< tPDPtr, PrototypeVertexPtr > &p1, const pair< tPDPtr, PrototypeVertexPtr > &p2) const
Operator for the ordering.