herwig is hosted by Hepforge, IPPP Durham
Herwig  7.1.5
PrototypeVertex.h
1 // -*- C++ -*-
2 //
3 // PrototypeVertex.h is a part of Herwig - A multi-purpose Monte Carlo event generator
4 // Copyright (C) 2002-2017 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 
21 namespace Herwig {
22 using namespace ThePEG;
23 using Helicity::VertexBasePtr;
24 
25 class PrototypeVertex;
26 ThePEG_DECLARE_POINTERS(Herwig::PrototypeVertex,PrototypeVertexPtr);
27 
29 typedef pair<unsigned int, double> CFPair;
30 
31 
41  bool operator() (tcPDPtr p1, tcPDPtr p2) {
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 
65 typedef multiset<pair< tPDPtr, PrototypeVertexPtr >,VertexOrdering > OrderedVertices;
66 
70 typedef multiset<PDPtr,ParticleOrdering> OrderedParticles;
71 
75 class PrototypeVertex : public Base {
76 
77 public:
78 
82  PrototypeVertex() : npart(0), possibleOnShell(false) {}
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 
120  mutable OrderedParticles outPart;
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 
236 inline 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 
259 inline 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 
328 struct NBVertex {
329 
333  NBVertex(PrototypeVertexPtr proto = PrototypeVertexPtr() );
334 
339 
343  mutable OrderedParticles outgoing;
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
408  << x.colourFlow << x.largeNcColourFlow;
409  return os;
410 }
411 
418  NBDiagram & x) {
419  is >> x.incoming >> x.channelType >> x.outgoing >> x.vertices >> x.vertex
420  >> x.colourFlow >> x.largeNcColourFlow;
421  return is;
422 }
423 
427 inline 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 
448 inline 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 */
A struct to order the particles in the same way as in the DecayMode&#39;s.
bool possibleOnShell
Can have on-shell intermediates.
ThePEG::Ptr< ParticleData >::transient_pointer tPDPtr
list< pair< PDPtr, NBVertex > > vertices
The vertices.
PrototypeVertex()
Default Constructor.
A struct to order the particles in the same way as in the DecayModes.
unsigned int npart
Number of particles.
bool operator==(const HPDiagram &x, const HPDiagram &y)
Test whether two diagrams are identical.
Definition: HPDiagram.h:98
vector< CFPair > largeNcColourFlow
Store colour flow at information.
Energy outgoingMass()
Total mass of all the outgoing particles.
Energy outgoingConstituentMass()
Total constituent mass of all the outgoing particles.
tPDPtr incoming
Incoming particle.
ostream & operator<<(ostream &, const DecayIntegrator &)
Output information on the DecayIntegrator for debugging purposes.
VertexBasePtr vertex
The vertex for the interaction.
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&#39;s.
PrototypeVertex(tPDPtr in, OrderedVertices out, VertexBasePtr v, int n)
Constructor.
A simple vertex for the N-body diagram.
OrderedParticles outPart
Outgoing particles.
OrderedVertices outgoing
Outgoing particles.
void incrementN(int in)
Increment the number of particles.
vector< T > & operator>>(vector< T > &tv, U &u)
ThePEG::Ptr< ParticleData >::transient_const_pointer tcPDPtr
The NBDiagram struct contains information about a decay that has been automatically generated...
Storage of a potenital n-body decay.
tPDPtr incoming
Incoming particle.
VertexBasePtr vertex
The vertex.
void setOutgoing() const
Set the outgoing particles.
OrderedParticles outgoing
Outgoing particles.
-*- C++ -*-
tPrototypeVertexPtr parent
The parent of the vertex.
Energy incomingMass()
Mass of the incoming particle.
vector< CFPair > colourFlow
Store colour flow at information.
constexpr ZeroUnit ZERO
bool checkExternal(bool first=true)
Check the external particles.
vector< unsigned int > channelType
The type of channel.