Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-06 09:38:21

0001 // -*- C++ -*-
0002 //
0003 // Particle.h is a part of ThePEG - Toolkit for HEP Event Generation
0004 // Copyright (C) 1999-2019 Leif Lonnblad
0005 //
0006 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
0007 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
0008 //
0009 #ifndef ThePEG_Particle_H
0010 #define ThePEG_Particle_H
0011 // This is the decalaration of the Particle class.
0012 
0013 #include "EventConfig.h"
0014 #include "ThePEG/Vectors/Lorentz5Vector.h"
0015 #include "ThePEG/Vectors/LorentzRotation.h"
0016 #include "ThePEG/Utilities/ClassDescription.h"
0017 #include "ThePEG/EventRecord/MultiColour.h"
0018 #include "ThePEG/EventRecord/SpinInfo.h"
0019 #include "ThePEG/PDT/ParticleData.h"
0020 
0021 namespace ThePEG {
0022 
0023 /**
0024  * The Particle class is used to describe an instance of a
0025  * particle. Properties of the corresponding particle type can be
0026  * accessed through a pointer to a ParticleData object.
0027  *
0028  * A Particle object contains pointers to other particles, such as a
0029  * list of parents and a list of children. It may also contain a
0030  * pointer to the previous or next instance of the same physical
0031  * particle if the properties of a given particle has been changed
0032  * during the generation. Coloured particles contains pointers to
0033  * ColourLine defining the colour connections to other particles.
0034  *
0035  * The Particle also has a pointer to the Step object where it was
0036  * first introduced in the Event.
0037  *
0038  * When printing a particle the format of the output is governed by
0039  * the static <code>outputFormat</code> string. When a particle is sent
0040  * to an <code>ostream</code>, the format string is written but with
0041  * keys prefixed by the <code>\%</code> character replaced with
0042  * infromation about the particle as follows:<BR> <code>\%\%</code> is
0043  * replaced by a singel <code>\%</code><BR> <code>\%C</code> sets a flag so
0044  * that subsequent output of children and parents etc. will contain
0045  * colour information.<BR> <code>\%n</code> is replaced by the particles
0046  * number in a fied ow width<BR> <code>\%s</code> is replaced by the name
0047  * of the particle<BR> <code>\%i</code> is replaced by the id number of
0048  * the particle type<BR><code>\%x, \%y, \%z, \%e, \%m</code> is replaced by
0049  * the x-, y-, z-, energy- and mass-component of the particles
0050  * momentum respectively<BR><code>\%dx, \%dy, \%dz, \%dt, \%dT</code> is
0051  * replaced by the x-, y-, z-, time- and invariant time-component of
0052  * the particles lifeLength respectively<BR><code>\%Vx, \%Vy, \%Vz,
0053  * \%Vt</code> is replaced by the x-, y-, z- and time-component of the
0054  * creation point relative to the vertex of the
0055  * collision.<BR><code>\%Lx, \%Ly, \%Lz, \%Lt</code> is replaced by the x-,
0056  * y-, z- and time-component of the creation point in the current
0057  * lab-system.<BR> <code>\%p[,]</code> is replaced by a list (of numbers)
0058  * of the particles parents enclosed by <code>[</code> and <code>]</code>
0059  * and separated by <code>,</code>, The parent from which the particle
0060  * inherits its (anti-) colour is marked by a (-)+<BR>
0061  * <code>\%c(,)</code> is replaced by a list (of numbers) of the
0062  * particles children enclosed by <code>(</code> and <code>)</code> and
0063  * separated by <code>,</code>, The child which inherits the particles
0064  * (anti-) colour is marked by a (-)+<BR> <code>\%&gt;</code> is replaced
0065  * by the number of the colour neighbor<BR> <code>\%&lt;</code> is
0066  * replaced by the number of the anti-colour neighbor<BR>
0067  * <code>\%^</code> is replaced by the number of the previous instance of
0068  * the same physical particle<BR> <code>\%v</code> is replaced by the
0069  * number of the next instance of the same physical particle.<BR>
0070  * <code>\%l{,}</code> is replaced by the indices of the colour lines to
0071  * which this particle is connected enclosed by <code>{</code> and
0072  * <code>}</code> and separated by <code>,</code>, The line corresponding
0073  * to the (anti-) colour of the particle is prefixed by a (-)+
0074  *
0075  * @see Event
0076  * @see Collision
0077  * @see Step
0078  * @see SubProcess
0079  * @see Lorentz5Vector
0080  * @see ColourLine
0081  * @see ColourBase 
0082  */
0083 class Particle: public EventRecordBase {
0084 
0085 public:
0086 
0087   /** Most of the Event classes are friends with each other. */
0088   friend class Event;
0089   /** Most of the Event classes are friends with each other. */
0090   friend class Collision;
0091   /** Most of the Event classes are friends with each other. */
0092   friend class Step;
0093   /** Most of the Event classes are friends with each other. */
0094   friend class SubProcess;
0095   /** ParticleData needs to be a friend. */
0096   friend class ParticleData;
0097 
0098   struct ParticleRep;
0099 
0100 public:
0101 
0102   /**
0103    * Standard Constructor. Note that the default constructor is
0104    * private - there is no particle without a pointer to a
0105    * ParticleData object.
0106    */
0107   Particle(tcEventPDPtr newData) : theData(newData), theRep(0), theStatus(0) {}
0108 
0109   /**
0110    * Copy constructor.
0111    */
0112   Particle(const Particle &);
0113 
0114   /**
0115    * Destructor.
0116    */
0117   virtual ~Particle();
0118   //@}
0119 
0120   /** @name Functions relating to ancestry of particles. */
0121   //@{
0122   /**
0123    * Returns true if and only if this particle has decayed.
0124    */
0125   bool decayed() const {
0126     return hasRep() && !rep().theChildren.empty();
0127   }
0128 
0129   /**
0130    * The list of decay products.
0131    */
0132   const ParticleVector & children() const {
0133     static const ParticleVector null;
0134     return hasRep() ? rep().theChildren : null;
0135   }
0136 
0137   /**
0138    * Add a child (the childs parent pointer will be set accordingly).
0139    */
0140   void addChild(tPPtr c) {
0141       rep().theChildren.push_back(c);
0142       (c->rep()).theParents.push_back(this);
0143   }
0144 
0145   /**
0146    * Remove the given child from the list of children of this particle
0147    * (the corresponding parent pointer of the child will also be
0148    * removed).
0149    */
0150   void abandonChild(tPPtr child) {
0151     removeChild(child);
0152     child->removeParent(this);
0153   }
0154 
0155   /**
0156    * The list of parent particles.
0157    */
0158   const tParticleVector & parents() const {
0159     static const tParticleVector null;
0160     return hasRep() ? rep().theParents : null;
0161   }
0162 
0163   /**
0164    * Return a set of neighboring particles coming from the same decay
0165    * as this one. The return value is a newly recalculated set
0166    * every time. It must be stored to be used further, do not directly call
0167    * e.g. siblings().begin() or siblings().end()!
0168    */
0169   tParticleSet siblings() const;
0170 
0171   /**
0172    * Undo the decay of this particle, removing all children (and
0173    * grand children ...) from the event record
0174    */
0175   void undecay() {
0176     if ( hasRep() ) {
0177       rep().theChildren.clear();
0178       rep().theNext = tPPtr();
0179     }
0180   }
0181 
0182   /**
0183    * If this particle has decayed set the corresponding decay mode.
0184    */
0185   void decayMode(tDMPtr dm) { rep().theDecayMode = dm; }
0186 
0187   /**
0188    * If this particle has decayed get the corresponding decay mode.
0189    */
0190   tDMPtr decayMode() const {
0191     return hasRep() ? rep().theDecayMode : tDMPtr();
0192   }
0193 
0194   /**
0195    * Next instance. Pointer to another instance of the same
0196    * physical particle in later steps.
0197    */
0198   tPPtr next() const {
0199     return hasRep() ? rep().theNext : PPtr();
0200   }
0201 
0202   /**
0203    * Previous instance. Pointer to another instance of the same
0204    * physical particle in earlier steps.
0205    */
0206   tPPtr previous() const {
0207     return hasRep() ? rep().thePrevious : tPPtr();
0208   }
0209 
0210   /**
0211    * Original instance. If there exists another previous instance of
0212    * this particle return this instance (recursively).
0213    */
0214   tcPPtr original() const {
0215     return previous() ? tcPPtr(previous()->original()) : tcPPtr(this);
0216   }
0217 
0218   /**
0219    * Original instance. If there exists another previous instance of
0220    * this particle return this instance (recursively).
0221    */
0222   tPPtr original() {
0223     return previous() ? previous()->original() : tPPtr(this);
0224   }
0225 
0226 
0227   /**
0228    * Final instance. If there exists another subsequent instance of
0229    * this particle return this instance (recursively).
0230    */
0231   tcPPtr final() const {
0232     return next() ? tcPPtr(next()->final()) : tcPPtr(this);
0233   }
0234 
0235   /**
0236    * Final instance. If there exists another subsequent instance of
0237    * this particle return this instance (recursively).
0238    */
0239   tPPtr final() {
0240     return next() ? next()->final() : tPPtr(this);
0241   }
0242 
0243   //@}
0244 
0245   /** @name Relations to the Event and Step. */
0246   //@{
0247   /**
0248    * Get the first Step object where this particle occurred.
0249    */
0250   tStepPtr birthStep() const { 
0251     return hasRep() ? rep().theBirthStep : tStepPtr();
0252   }
0253 
0254   /**
0255    * Get the order-number for this particle in the current event.
0256    */
0257   int number() const { 
0258     return hasRep() ? rep().theNumber : 0; 
0259   }
0260 
0261   /**
0262    * Get the status code of the particle
0263    */
0264   int status() const { return theStatus; }
0265 
0266   /**
0267    * Set the status code of the particle
0268    */
0269   void status(int n) { theStatus = n; }
0270   //@}
0271 
0272   /** @name Access the underlying ParticleData object. */
0273   //@{
0274   /**
0275    * Access the ParticleData object of this particle type
0276    */
0277   const ParticleDataClass & data() const { return *theData; }
0278 
0279   /**
0280    * Access the ParticleData object of this particle type
0281    */
0282   tcEventPDPtr dataPtr() const { return theData; }
0283 
0284   /**
0285    * Return the PDG name of this particle.
0286    */
0287   const string & PDGName() const { return data().PDGName(); }
0288 
0289   /**
0290    * Return the PDG id number of this particle.
0291    */
0292   long id() const { return data().id(); }
0293   //@}
0294 
0295   /** @name Functions to access the momentum. */
0296   //@{
0297   /**
0298    * Return the momentum of this particle.
0299    */
0300   const Lorentz5Momentum & momentum() const { return theMomentum; }
0301 
0302   /**
0303    * Set the 3-momentum of this particle. The energy is set to be
0304    * consistent with the mass.
0305    */
0306   void set3Momentum(const Momentum3 & p) {
0307     theMomentum.setVect(p);
0308     theMomentum.rescaleEnergy();
0309   }
0310 
0311   /**
0312    * Set the momentum of this particle. Afterwards, the underlying
0313    * Lorentz5Momentum may have inconsistent mass.
0314    */
0315   void setMomentum(const LorentzMomentum & p) {
0316     theMomentum = p;
0317   }
0318 
0319   /**
0320    * Set the momentum and mass.
0321    */
0322   void set5Momentum(const Lorentz5Momentum & p) {
0323     theMomentum = p;
0324   }
0325 
0326   /**
0327    * Acces the mass of this particle.
0328    */
0329   Energy mass() const { return momentum().mass(); }
0330 
0331   /**
0332    * Acces the mass of this particle type.
0333    */
0334   Energy nominalMass() const { return data().mass(); }
0335 
0336   /**
0337    * Get the scale at which this particle is considered resolved.
0338    */
0339   Energy2 scale() const { 
0340     return hasRep() ? rep().theScale : -1.0*GeV2;
0341   }
0342 
0343   /**
0344    * Set the scale at which this particle is considered resolved.
0345    */
0346   void scale(Energy2 q2) { rep().theScale = q2; }
0347 
0348   /**
0349    * Get the scale above which this particle should
0350    * not radiate.
0351    */
0352   Energy2 vetoScale() const { 
0353     return hasRep() ? rep().theVetoScale : -1.0*GeV2;
0354   }
0355 
0356   /**
0357    * Set the scale above which this particle should
0358    * not radiate.
0359    */
0360   void vetoScale(Energy2 q2) { rep().theVetoScale = q2; }
0361 
0362   /**
0363    * Return the transverse mass (squared), calculated from the energy
0364    * and the longitudinal momentum.
0365    */
0366   Energy2 mt2() const { return sqr(momentum().t()) - sqr(momentum().z()); }
0367 
0368   /**
0369    * Return the transverse mass (squared), calculated from the energy
0370    * and the longitudinal momentum.
0371    */
0372   Energy mt() const { return sqrt(mt2()); }
0373 
0374   /**
0375    * Return the transverse mass (squared), calculated from the mass
0376    * and the transverse momentum.
0377    */
0378   Energy2 perpmass2() const { return momentum().perp2() + momentum().mass2(); }
0379 
0380   /**
0381    * Return the transverse mass (squared), calculated from the mass
0382    * and the transverse momentum.
0383    */
0384   Energy perpmass() const { return sqrt(perpmass2()); }
0385 
0386   /**
0387    * Return the (pseudo) rapidity.
0388    */
0389   double rapidity() const {
0390     return ( Pplus() > ZERO && Pminus() > ZERO )?
0391       0.5*log(Pplus()/Pminus()) : Constants::MaxFloat;
0392   }
0393 
0394   /**
0395    * Return the (pseudo) rapidity.
0396    */
0397   double eta() const {
0398     Energy rho = momentum().rho();
0399     return rho > abs(momentum().z())?
0400       0.5*log((rho+momentum().z())/(rho-momentum().z())) : Constants::MaxFloat;
0401   }
0402 
0403   /**
0404    * Return the positive and negative light-cone momenta.
0405    */
0406   Energy Pplus() const { return momentum().plus(); }
0407   /**
0408    * Return the positive and negative light-cone momenta.
0409    */
0410   Energy Pminus() const { return momentum().minus(); }
0411   //@}
0412 
0413   /** @name Functions to access the position. */
0414   //@{
0415   /**
0416    * The creation vertex of this particle. The point is given
0417    * relative to the collision vertex.
0418    */
0419   const LorentzPoint & vertex() const {
0420     static const LorentzPoint null;
0421     return hasRep() ? rep().theVertex : null;
0422   }
0423 
0424   /**
0425    * The creation vertex of this particle. The absolute
0426    * position in the lab is given.
0427    */
0428   LorentzPoint labVertex() const;
0429 
0430   /**
0431    * The decay vertex of this particle. The point is given
0432    * relative to the collision vertex.
0433    */
0434   LorentzPoint decayVertex() const { 
0435     return vertex() + lifeLength();
0436   }
0437 
0438   /**
0439    * The decay vertex of this particle. The absolute
0440    * position in the lab is given.
0441    */
0442   LorentzPoint labDecayVertex() const {
0443     return labVertex() + lifeLength();
0444   }
0445 
0446   /**
0447    * The life time/length. Return the Lorentz vector connecting the
0448    * creation to the decay vertes.
0449    */
0450   const Lorentz5Distance & lifeLength() const {
0451     static const Lorentz5Distance null;
0452     return hasRep() ? rep().theLifeLength : null;
0453   }
0454 
0455   /**
0456    * Set the creation vertex relative to the collision vertex.
0457    */
0458   void setVertex(const LorentzPoint & p) {
0459     rep().theVertex = p;
0460   }
0461 
0462   /**
0463    * Set the creation vertex in the lab frame of this particle.
0464    */
0465   void setLabVertex(const LorentzPoint &);
0466 
0467   /**
0468    * Set the life length of this particle. The life time will be
0469    * automatically rescaled to be consistent with the invariant
0470    * distance.
0471    */
0472   void setLifeLength(const Distance & d) {
0473     rep().theLifeLength.setVect(d);
0474     rep().theLifeLength.rescaleEnergy();
0475   }
0476 
0477   /**
0478    * Set the life time/length of a particle. The invariant distance
0479    * may become inconsistent.
0480    */
0481   void setLifeLength(const LorentzDistance & d) {
0482     rep().theLifeLength = d;
0483   }
0484 
0485   /**
0486    * Set the life time/length of a particle.
0487    */
0488   void setLifeLength(const Lorentz5Distance & d) {
0489     rep().theLifeLength = d;
0490   }
0491 
0492   /**
0493    * The invariant life time of this particle.
0494    */
0495   Time lifeTime() const { return lifeLength().m(); }
0496 
0497   //@}
0498 
0499   /** @name Functions for (Lorentz) transformations. */
0500   //@{
0501   /**
0502    * Do Lorentz transformations on this particle.
0503    */
0504   void transform(const LorentzRotation & r);
0505 
0506   /**
0507    * Do Lorentz transformations on this particle. \a bx, \a by and \a
0508    * bz are the boost vector components.
0509    */
0510   void boost(double bx, double by, double bz) {
0511     transform(LorentzRotation(Boost(bx, by, bz)));
0512   }
0513 
0514   /**
0515    * Do Lorentz transformations on this particle. \a b is the boost
0516    * vector.
0517    */
0518   void boost(const Boost & b) { transform(LorentzRotation(b)); }
0519 
0520   /**
0521    * Rotate around the x-axis.
0522    */
0523   void rotateX(double a);
0524 
0525   /**
0526    * Rotate around the y-axis.
0527    */
0528   void rotateY(double a);
0529 
0530   /**
0531    * Rotate around the z-axis.
0532    */
0533   void rotateZ(double a);
0534 
0535   /**
0536    * Rotate around the given \a axis.
0537    */
0538   void rotate(double a, const Axis & axis);
0539 
0540   /**
0541    * Mirror in the xy-plane.
0542    */
0543   void mirror() { theMomentum.setZ(-theMomentum.z()); }
0544 
0545   /**
0546    * Do Lorentz transformations on this particle and its decendants.
0547    */
0548   void deepTransform(const LorentzRotation & r);
0549 
0550   /**
0551    * Do Lorentz transformations on this particle and its
0552    * decendants. \a bx, \a by and \a bz are the boost vector
0553    * components.
0554    */
0555   void deepBoost(double bx, double by, double bz) {
0556     deepTransform(LorentzRotation(Boost(bx, by, bz)));
0557   }
0558 
0559   /**
0560    * Do Lorentz transformations on this particle and its
0561    * decendants. \a b is the boost vector.
0562    */
0563   void deepBoost(const Boost & b) { deepTransform(LorentzRotation(b)); }
0564 
0565   /**
0566    * Rotate this particle and its decendants around the x-axis.
0567    */
0568   void deepRotateX(double a);
0569 
0570   /**
0571    * Rotate this particle and its decendants around the y-axis.
0572    */
0573   void deepRotateY(double a);
0574 
0575   /**
0576    * Rotate this particle and its decendants around the z-axis.
0577    */
0578   void deepRotateZ(double a);
0579 
0580   /**
0581    * Rotate this particle and its decendants around the given \a axis.
0582    */
0583   void deepRotate(double a, const Axis & axis);
0584 
0585   //@}
0586 
0587   /** @name Functions controlling possible mass/momentum inconsistencies. */
0588   //@{
0589   /**
0590    * Return the relative inconsistency in the mass component.
0591    */
0592   double massError() const { return theMomentum.massError(); }
0593 
0594   /**
0595    * Return the relative inconsistency in the energy component.
0596    */
0597   double energyError() const { return theMomentum.energyError(); }
0598 
0599   /**
0600    * Return the relative inconsistency in the spatial components.
0601    */
0602   double rhoError() const { return theMomentum.rhoError(); }
0603 
0604   /**
0605    * Rescale energy, so that the invariant length/mass of the
0606    * LorentzVector agrees with the current one.
0607    */
0608   void rescaleEnergy() { theMomentum.rescaleEnergy(); }
0609 
0610   /**
0611    * Rescale spatial component, so that the invariant length/mass of
0612    * the LorentzVector agrees with the current one.
0613    */
0614   void rescaleRho() { theMomentum.rescaleRho(); }
0615 
0616   /**
0617    * Set the invariant length/mass member, so that it agrees with the
0618    * invariant length/mass of the LorentzVector.
0619    */
0620   void rescaleMass() { theMomentum.rescaleMass(); }
0621   //@}
0622 
0623   /** @name Acces incormation about colour connections */
0624   //@{
0625   /**
0626    * True if this particle has colour information. To determine if
0627    * this particle is actually coloured, the coloured(), hasColour() or
0628    * hasAntiColour() methods should be used instead.
0629    */
0630   bool hasColourInfo() const {
0631     return hasRep() && rep().theColourInfo;
0632   }
0633 
0634   /**
0635    * Return the colour lines to which this particles anti-colour is
0636    * connected.
0637    */
0638   tColinePtr antiColourLine() const {
0639     return hasColourInfo() ? colourInfo()->antiColourLine() : tColinePtr();
0640   }
0641 
0642   /**
0643    * Return the colour lines to which this particles (\a anti-)colour
0644    * is connected.
0645    */
0646   tColinePtr colourLine(bool anti = false) const {
0647     if ( anti ) return antiColourLine();
0648     return hasColourInfo() ? colourInfo()->colourLine() : tColinePtr();
0649   }
0650 
0651   /**
0652    * Return true if the particle is connected to the given (\a anti-)
0653    * colour \a line.
0654    */
0655   bool hasColourLine(tcColinePtr line, bool anti = false) const {
0656     return hasColourInfo() ? colourInfo()->hasColourLine(line, anti) : false;
0657   }
0658 
0659   /**
0660    * Return true if the particle is connected to the given anti-colour
0661    * \a line.
0662    */
0663   bool hasAntiColourLine(tcColinePtr line) const {
0664     return hasColourLine(line, true);
0665   }
0666 
0667   /**
0668    * True if this particle type is not a colour singlet.
0669    */
0670   bool coloured() const { return data().coloured(); }
0671 
0672   /**
0673    * True if this particle type carries (\a anti-)colour.
0674    */
0675   bool hasColour(bool anti = false) const { return data().hasColour(anti); }
0676 
0677   /**
0678    * True if this particle type carries anti-colour.
0679    */
0680   bool hasAntiColour() const { return data().hasAntiColour(); }
0681 
0682   /**
0683    * Get the ColourBase object.
0684    */
0685   tcCBPtr colourInfo() const {
0686     return hasRep() ? rep().theColourInfo : CBPtr();
0687   }
0688 
0689   /**
0690    * Get the ColourBase object.
0691    */
0692   tCBPtr colourInfo() {
0693     if ( !rep().theColourInfo ) {
0694       switch(theData->iColour()) {
0695       case PDT::Colour6: 
0696       case PDT::Colour6bar:
0697     rep().theColourInfo = new_ptr(MultiColour());
0698     break;
0699       default:
0700     rep().theColourInfo = new_ptr(ColourBase());
0701       }
0702     }
0703     return rep().theColourInfo;
0704   }
0705 
0706   /**
0707    * Set the ColourBase object.
0708    */
0709   void colourInfo(tCBPtr c) {
0710     rep().theColourInfo = c;
0711   }
0712 
0713   /**
0714    * Get a pointer to the colour neighbor. Returns a particle in the
0715    * range \a first to \a last which colour is connected to the same
0716    * line as this particles anti-colour. If \a anti is true return
0717    * antiColourNeighbour().
0718    */
0719   template <typename Iterator>
0720   typename std::iterator_traits<Iterator>::value_type
0721   colourNeighbour(Iterator first, Iterator last, bool anti = false) const;
0722 
0723   /**
0724    * Get a pointer to the anti-colour neighbor. Returns a particle in
0725    * the range \a first to \a last which anti-colour is
0726    * connected to the same line as this particles colour.
0727    */
0728   template <typename Iterator>
0729   typename std::iterator_traits<Iterator>::value_type
0730   antiColourNeighbour(Iterator first, Iterator last) const {
0731     return colourNeighbour(first, last, true);
0732   }
0733 
0734   /**
0735    * Set the colour neighbor. Connects the given particles colour to
0736    * the same colour line as this particles anti-colour. If \a anti is
0737    * true call antiColourNeighbour(tPPtr).
0738    */
0739   void colourNeighbour(tPPtr, bool anti = false);
0740 
0741   /**
0742    * Set the anti-colour neighbor. Connects the given particles
0743    * anti-colour to the same colour line as this particles colour.
0744    */
0745   void antiColourNeighbour(tPPtr p) { colourNeighbour(p, true); }
0746 
0747   /**
0748    * Connect colour. Create a colour line connecting to it this
0749    * particles colour and the given particles anti-colour.
0750    */
0751   void antiColourConnect(tPPtr neighbour) {
0752     colourConnect(neighbour, true);
0753   }
0754 
0755   /**
0756    * Connect colour. Create a colour line connecting to it this
0757    * particles anti-colour and the given particles colour. If \a anti
0758    * is true call antiColourConnect(tPPtr).
0759    */
0760   void colourConnect(tPPtr neighbour, bool anti = false) {
0761     colourNeighbour(neighbour, anti);
0762   }
0763 
0764   /**
0765    * Incoming colour. Return the parent particle which colour is
0766    * connected to the same colour line as this particle. If \a anti is
0767    * true return incomingAntiColour().
0768    */
0769   tPPtr incomingColour(bool anti = false) const;
0770 
0771   /**
0772    * Incoming anti-colour. Return the parent particle which
0773    * anti-colour is connected to the same colour line as this
0774    * particle.
0775    */
0776   tPPtr incomingAntiColour() const { return incomingColour(true); }
0777 
0778   /**
0779    * Set incoming colour. Connect this particles colour to the same
0780    * colour line as the given particle. If \a anti
0781    * is true call incomingAntiColour(tPPtr).
0782    */
0783   void incomingColour(tPPtr p, bool anti = false) { p->outgoingColour(this, anti); }
0784 
0785   /**
0786    * Set incoming anti-colour. Connect this particles anti colour to
0787    * the same colour line as the given particle.
0788    */
0789   void incomingAntiColour(tPPtr p) { p->outgoingColour(this, true); }
0790 
0791   /**
0792    * Outgoing colour. Return the daughter particle which colour is
0793    * connected to the same colour line as this particle. If \a anti is
0794    * true return outgoingAntiColour().
0795    */
0796   tPPtr outgoingColour(bool anti = false) const;
0797   /**
0798    * Outgoing anti-colour. Return the daughter particle which
0799    * anti-colour is connected to the same colour line as this
0800    * particle.
0801    */
0802   tPPtr outgoingAntiColour() const { return outgoingColour(true); }
0803 
0804   /**
0805    * Set outgoing colour. Connect this particles colour to the same
0806    * colour line as the given particle. If \a anti
0807    * is true call outgoingAntiColour(tPPtr).
0808    */
0809   void outgoingColour(tPPtr, bool anti = false);
0810 
0811   /**
0812    * Set outgoing anti-colour. Connect this particles anti-colour to
0813    * the same colour line as the given particle.
0814    */
0815   void outgoingAntiColour(tPPtr p) { outgoingColour(p, true); }
0816 
0817   /**
0818    * Specify colour flow. Calls outgoingColour(tPPtr,bool).
0819    */
0820   void colourFlow(tPPtr child, bool anti = false) {
0821     outgoingColour(child, anti);
0822   }
0823 
0824   /**
0825    * Specify anticolour flow. Calls outgoingAntiColour(tPPtr,bool).
0826    */
0827   void antiColourFlow(tPPtr child) { colourFlow(child, true); }
0828 
0829   /**
0830    * Remove all colour information;
0831    */
0832   void resetColour() {
0833     if ( hasColourInfo() ) rep().theColourInfo = CBPtr();
0834   }
0835 
0836   //@}
0837 
0838   /** @name Functions to access spin. */
0839   //@{
0840   /**
0841    * Return the Spin object.
0842    */
0843   tcSpinPtr spinInfo() const { 
0844     return hasRep() ? rep().theSpinInfo : SpinPtr(); 
0845   }
0846 
0847   /**
0848    * Return the Spin object.
0849    */
0850   tSpinPtr spinInfo() {
0851     return hasRep() ? rep().theSpinInfo : SpinPtr(); 
0852   }
0853 
0854   /**
0855    * Set the Spin object.
0856    */
0857   void spinInfo(tSpinPtr s) { rep().theSpinInfo = s; }
0858   //@}
0859 
0860   /** @name Accessing user-defined information. */
0861   //@{
0862   /**
0863    * Access user-defined information as a vector of EventInfoBase pointers.
0864    */
0865   const EIVector & getInfo() const {
0866     static const EIVector null;
0867     return hasRep() ? rep().theExtraInfo : null;
0868   }
0869 
0870   /**
0871    * Access user-defined information as a vector of EventInfoBase pointers.
0872    */
0873   EIVector & getInfo() { return rep().theExtraInfo; }
0874   //@}
0875 
0876 public:
0877 
0878   /** @name Accessing user-defined information. */
0879   //@{
0880   /**
0881    * True if this particle has instantiated the object with
0882    * information other than type and momentum.
0883    */
0884   bool hasRep() const { return theRep; }
0885 
0886   /**
0887    * If this particle has only a type and momentum, instantiate the
0888    * rest of the information.
0889    */
0890   void initFull();
0891 
0892   //@}
0893 
0894 public:
0895 
0896   /** @name Input and output functions. */
0897   //@{
0898   /**
0899    * Standard function for writing to a persistent stream.
0900    */
0901   void persistentOutput(PersistentOStream &) const;
0902 
0903   /**
0904    * Standard function for reading from a persistent stream.
0905    */
0906   void persistentInput(PersistentIStream &, int);
0907 
0908   //@}
0909 
0910   /**
0911    * Print particle info to a stream \a os. The \a step is used to
0912    * access information about colour neighbors and other struff.
0913    */
0914   ostream & print(ostream & os, tcStepPtr step = tcStepPtr()) const;
0915 
0916   /**
0917    * Print a range of particles.
0918    */
0919   template <typename Iterator>
0920   static void PrintParticles(ostream & os, Iterator first, Iterator last,
0921                  tcStepPtr step = tcStepPtr());
0922 
0923   /**
0924    * Print a container of particles.
0925    */
0926   template <typename Cont>
0927   static inline void PrintParticles(ostream & os, const Cont & c,
0928                  tcStepPtr step = tcStepPtr()) {
0929     PrintParticles(os, c.begin(), c.end(), step);
0930   }
0931    
0932   /**
0933    * Standard Init function. @see Base::Init().
0934    */
0935   static void Init();
0936 
0937   /**
0938    * Specify how to print particles. The format string is analogous to
0939    * the one used by eg. the unix 'date' command as described above.
0940    */
0941   static string outputFormat;
0942 
0943 private:
0944 
0945   /**
0946    * Standard clone function.
0947    */
0948   virtual PPtr clone() const;
0949 
0950   /**
0951    * Rebind to cloned objects. When an Event is cloned, a shallow
0952    * copy is done first, then all <code>Particle</code>s etc, are
0953    * cloned, and finally this method is used to see to that the
0954    * pointers in the cloned Particle points to the cloned objects.
0955    */
0956   virtual void rebind(const EventTranslationMap &);
0957 
0958   /**
0959    * Set the order-number for this particle in the current event.
0960    */
0961   void number(int n) { rep().theNumber = n; }
0962 
0963   /**
0964    * Remove the given particle from the list of children.
0965    */
0966   void removeChild(tPPtr c) {
0967     if ( hasRep() )
0968       rep().theChildren.erase(remove(rep().theChildren.begin(),
0969                      rep().theChildren.end(), c),
0970                   rep().theChildren.end());
0971   }
0972 
0973   /**
0974    * Remove the given particle from the list of parents.
0975    */
0976   void removeParent(tPPtr p) {
0977     if ( hasRep() )
0978       rep().theParents.erase(remove(rep().theParents.begin(),
0979                     rep().theParents.end(), p),
0980                  rep().theParents.end());
0981   }
0982 
0983   /**
0984    * Set the mass of this particle.
0985    */
0986   void mass(Energy m) { theMomentum.setMass(m); }
0987 
0988   /**
0989    * Set the invaiant life time of this particle.
0990    */
0991   void lifeTime(Length t) { rep().theLifeLength.setTau(t); }
0992 
0993   /**
0994    * Return a reference to the bulk information of this particle. if
0995    * no ParticleRep object exists, one is created.
0996    */
0997   ParticleRep & rep() {
0998     if ( !hasRep() ) initFull();
0999     return *theRep;
1000   }
1001 
1002   /**
1003    * Return a reference to the bulk information of this particle. if
1004    * no ParticleRep object exists, we return the default values.
1005    */
1006   const ParticleRep & rep() const {
1007     static const ParticleRep null;
1008     return hasRep() ? *theRep : null;
1009   }
1010 
1011   /**
1012    * The pointer to the ParticleData object
1013    */
1014   cEventPDPtr theData;
1015 
1016   /**
1017    * The momentum.
1018    */
1019   Lorentz5Momentum theMomentum;
1020 
1021   /**
1022    * The rest of the information in this particle is only instantiated
1023    * if needed.
1024    */
1025   ParticleRep * theRep;
1026 
1027   /**
1028    * The status code of the particle
1029    */
1030   int theStatus;
1031 
1032 public:
1033 
1034   /**
1035    * This class is used internally in the Particle class to represent
1036    * information besides momentum and type. A corresponding object
1037    * will only be instantiated if needed to save memory and time when
1038    * temporarily creating particles.
1039    */
1040   struct ParticleRep {
1041 
1042     /**
1043      * Default constructor.
1044      */
1045     ParticleRep() : theScale(-1.0*GeV2), theVetoScale(-1.0*GeV2), theNumber(0) {}
1046 
1047     /**
1048      * Copy constructor.
1049      */
1050     ParticleRep(const ParticleRep &);
1051 
1052     /**
1053      * The pointers to the parents.
1054      */
1055     tParticleVector theParents;
1056 
1057     /**
1058      * The pointers to the children.
1059      */
1060     ParticleVector theChildren;
1061 
1062     /**
1063      * The pointer to the previous instance.
1064      */
1065     tPPtr thePrevious;
1066 
1067     /**
1068      * The pointer to the next instance.
1069      */
1070     PPtr theNext;
1071 
1072     /**
1073      * If this particle has decayed this is the pointer to the
1074      * corresponding decay mode.
1075      */
1076     tDMPtr theDecayMode;
1077 
1078     /**
1079      * The pointer to the first step where this particle occurred.
1080      */
1081     tStepPtr theBirthStep;
1082 
1083     /**
1084      * The creation point.
1085      */
1086     LorentzPoint theVertex;
1087 
1088     /**
1089      * The life time/length.
1090      */
1091     Lorentz5Distance theLifeLength;
1092 
1093     /**
1094      * the resolution scale.
1095      */
1096     Energy2 theScale;
1097 
1098     /**
1099      * the veto scale.
1100      */
1101     Energy2 theVetoScale;
1102 
1103     /**
1104      * The order-number for this particle in the current event.
1105      */
1106     int theNumber;
1107 
1108     /**
1109      * A pointer to the colour information object.
1110      */
1111     CBPtr theColourInfo;
1112 
1113     /**
1114      * Spin information
1115      */
1116     SpinPtr theSpinInfo;
1117 
1118     /**
1119      * Additional used-defined information.
1120      */
1121     EIVector theExtraInfo;
1122 
1123   };
1124 
1125 public:
1126 
1127   /**
1128    * Print out debugging information for this object on std::cerr. To
1129    * be called from within a debugger via the debug() function.
1130    */
1131   virtual void debugme() const;
1132 
1133 protected:
1134 
1135   /**
1136    * Private default constructor must only be used by the
1137    * PersistentIStream class via the ClassTraits<Particle> class.
1138    */
1139   Particle() : theRep(0), theStatus(0) {}
1140 
1141   /**
1142    * The ClassTraits<Particle> class must be a friend to be able to
1143    * use the private default constructor.
1144    */
1145   friend struct ClassTraits<Particle>;
1146 
1147 private:
1148 
1149   /**
1150    * Private and non-existent assignment.
1151    */
1152   Particle & operator=(const Particle &) = delete;
1153 
1154   /**
1155    * Describe concrete class with persistent data.
1156    */
1157   static ClassDescription<Particle> initParticle;
1158 
1159 };
1160 
1161 /**
1162  * Write a Particle object to a stream.
1163  */
1164 ostream & operator<<(ostream &, const Particle &);
1165 
1166 
1167 /** @cond TRAITSPECIALIZATIONS */
1168 
1169 /** This template specialization informs ThePEG about the
1170  *  base class of Particle. */
1171 template <>
1172 struct BaseClassTrait<Particle,1>: public ClassTraitsType {
1173   /** Typedef of the first base class of Collision. */
1174   typedef EventRecordBase NthBase;
1175 };
1176 
1177 /** This template specialization informs ThePEG about the name of
1178  *  the Particle class and how to create it. */
1179 template <>
1180 struct ClassTraits<Particle>: public ClassTraitsBase<Particle> {
1181   /** Return a platform-independent class name */
1182   static string className() { return "ThePEG::Particle"; }
1183   /** Create a Particle object. */
1184   static TPtr create() { return TPtr::Create(Particle()); }
1185 };
1186 
1187 /** @endcond */
1188 
1189 }
1190 
1191 #ifndef ThePEG_TEMPLATES_IN_CC_FILE
1192 #include "Particle.tcc"
1193 #endif
1194 
1195 #endif /* ThePEG_Particle_H */