00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef ThePEG_Particle_H
00010 #define ThePEG_Particle_H
00011
00012
00013 #include "EventConfig.h"
00014 #include "ThePEG/Vectors/Lorentz5Vector.h"
00015 #include "ThePEG/Vectors/LorentzRotation.h"
00016 #include "ThePEG/Utilities/ClassDescription.h"
00017 #include "ThePEG/EventRecord/ColourBase.h"
00018 #include "ThePEG/EventRecord/SpinBase.h"
00019 #include "ThePEG/PDT/ParticleData.h"
00020
00021 namespace ThePEG {
00022
00083 class Particle: public EventRecordBase {
00084
00085 public:
00086
00088 friend class Event;
00090 friend class Collision;
00092 friend class Step;
00094 friend class SubProcess;
00096 friend class ParticleData;
00097
00098 struct ParticleRep;
00099
00100 public:
00101
00107 Particle(tcEventPDPtr newData) : theData(newData), theRep(0) {}
00108
00112 Particle(const Particle &);
00113
00117 virtual ~Particle();
00119
00125 bool decayed() const {
00126 return hasRep() && !rep().theChildren.empty();
00127 }
00128
00132 const ParticleVector & children() const {
00133 static const ParticleVector null;
00134 return hasRep() ? rep().theChildren : null;
00135 }
00136
00140 void addChild(tPPtr c) {
00141 rep().theChildren.push_back(c);
00142 (c->rep()).theParents.push_back(this);
00143 }
00144
00150 void abandonChild(tPPtr child) {
00151 removeChild(child);
00152 child->removeParent(this);
00153 }
00154
00158 const tParticleVector & parents() const {
00159 static const tParticleVector null;
00160 return hasRep() ? rep().theParents : null;
00161 }
00162
00169 tParticleSet siblings() const;
00170
00175 void undecay() {
00176 if ( hasRep() ) {
00177 rep().theChildren.clear();
00178 rep().theNext = tPPtr();
00179 }
00180 }
00181
00185 void decayMode(tDMPtr dm) { rep().theDecayMode = dm; }
00186
00190 tDMPtr decayMode() const {
00191 return hasRep() ? rep().theDecayMode : tDMPtr();
00192 }
00193
00198 tPPtr next() const {
00199 return hasRep() ? rep().theNext : PPtr();
00200 }
00201
00206 tPPtr previous() const {
00207 return hasRep() ? rep().thePrevious : tPPtr();
00208 }
00209
00214 tcPPtr original() const {
00215 return previous() ? tcPPtr(previous()->original()) : tcPPtr(this);
00216 }
00217
00222 tPPtr original() {
00223 return previous() ? previous()->original() : tPPtr(this);
00224 }
00225
00226
00231 tcPPtr final() const {
00232 return next() ? tcPPtr(next()->final()) : tcPPtr(this);
00233 }
00234
00239 tPPtr final() {
00240 return next() ? next()->final() : tPPtr(this);
00241 }
00242
00244
00250 tStepPtr birthStep() const {
00251 return hasRep() ? rep().theBirthStep : tStepPtr();
00252 }
00253
00257 int number() const {
00258 return hasRep() ? rep().theNumber : 0;
00259 }
00261
00267 const ParticleDataClass & data() const { return *theData; }
00268
00272 tcEventPDPtr dataPtr() const { return theData; }
00273
00277 const string & PDGName() const { return data().PDGName(); }
00278
00282 long id() const { return data().id(); }
00284
00290 const Lorentz5Momentum & momentum() const { return theMomentum; }
00291
00296 void set3Momentum(const Momentum3 & p) {
00297 theMomentum.setVect(p);
00298 theMomentum.rescaleEnergy();
00299 }
00300
00305 void setMomentum(const LorentzMomentum & p) {
00306 theMomentum = p;
00307 }
00308
00312 void set5Momentum(const Lorentz5Momentum & p) {
00313 theMomentum = p;
00314 }
00315
00319 Energy mass() const { return momentum().mass(); }
00320
00324 Energy nominalMass() const { return data().mass(); }
00325
00329 Energy2 scale() const {
00330 return hasRep() ? rep().theScale : -1.0*GeV2;
00331 }
00332
00336 void scale(Energy2 q2) { rep().theScale = q2; }
00337
00342 Energy2 mt2() const { return sqr(momentum().t()) - sqr(momentum().z()); }
00343
00348 Energy mt() const { return sqrt(mt2()); }
00349
00354 Energy2 perpmass2() const { return momentum().perp2() + momentum().mass2(); }
00355
00360 Energy perpmass() const { return sqrt(perpmass2()); }
00361
00365 double rapidity() const {
00366 return ( Pplus() > ZERO && Pminus() > ZERO )?
00367 0.5*log(Pplus()/Pminus()) : Constants::MaxFloat;
00368 }
00369
00373 double eta() const {
00374 Energy rho = momentum().rho();
00375 return rho > abs(momentum().z())?
00376 0.5*log((rho+momentum().z())/(rho-momentum().z())) : Constants::MaxFloat;
00377 }
00378
00382 Energy Pplus() const { return momentum().plus(); }
00386 Energy Pminus() const { return momentum().minus(); }
00388
00395 const LorentzPoint & vertex() const {
00396 static const LorentzPoint null;
00397 return hasRep() ? rep().theVertex : null;
00398 }
00399
00404 LorentzPoint labVertex() const;
00405
00410 LorentzPoint decayVertex() const {
00411 return vertex() + lifeLength();
00412 }
00413
00418 LorentzPoint labDecayVertex() const {
00419 return labVertex() + lifeLength();
00420 }
00421
00426 const Lorentz5Distance & lifeLength() const {
00427 static const Lorentz5Distance null;
00428 return hasRep() ? rep().theLifeLength : null;
00429 }
00430
00434 void setVertex(const LorentzPoint & p) {
00435 rep().theVertex = p;
00436 }
00437
00441 void setLabVertex(const LorentzPoint &);
00442
00448 void setLifeLength(const Distance & d) {
00449 rep().theLifeLength.setVect(d);
00450 rep().theLifeLength.rescaleEnergy();
00451 }
00452
00457 void setLifeLength(const LorentzDistance & d) {
00458 rep().theLifeLength = d;
00459 }
00460
00464 void setLifeLength(const Lorentz5Distance & d) {
00465 rep().theLifeLength = d;
00466 }
00467
00471 Time lifeTime() const { return lifeLength().m(); }
00472
00474
00480 void transform(const LorentzRotation & r);
00481
00486 void boost(double bx, double by, double bz) {
00487 transform(LorentzRotation(Boost(bx, by, bz)));
00488 }
00489
00494 void boost(const Boost & b) { transform(LorentzRotation(b)); }
00495
00499 void rotateX(double a);
00500
00504 void rotateY(double a);
00505
00509 void rotateZ(double a);
00510
00514 void rotate(double a, const Axis & axis);
00515
00519 void mirror() { theMomentum.setZ(-theMomentum.z()); }
00520
00524 void deepTransform(const LorentzRotation & r);
00525
00531 void deepBoost(double bx, double by, double bz) {
00532 deepTransform(LorentzRotation(Boost(bx, by, bz)));
00533 }
00534
00539 void deepBoost(const Boost & b) { deepTransform(LorentzRotation(b)); }
00540
00544 void deepRotateX(double a);
00545
00549 void deepRotateY(double a);
00550
00554 void deepRotateZ(double a);
00555
00559 void deepRotate(double a, const Axis & axis);
00560
00562
00568 double massError() const { return theMomentum.massError(); }
00569
00573 double energyError() const { return theMomentum.energyError(); }
00574
00578 double rhoError() const { return theMomentum.rhoError(); }
00579
00584 void rescaleEnergy() { theMomentum.rescaleEnergy(); }
00585
00590 void rescaleRho() { theMomentum.rescaleRho(); }
00591
00596 void rescaleMass() { theMomentum.rescaleMass(); }
00598
00606 bool hasColourInfo() const {
00607 return hasRep() && rep().theColourInfo;
00608 }
00609
00614 tColinePtr antiColourLine() const {
00615 return hasColourInfo() ? colourInfo()->antiColourLine() : tColinePtr();
00616 }
00617
00622 tColinePtr colourLine(bool anti = false) const {
00623 if ( anti ) return antiColourLine();
00624 return hasColourInfo() ? colourInfo()->colourLine() : tColinePtr();
00625 }
00626
00631 bool hasColourLine(tcColinePtr line, bool anti = false) const {
00632 return hasColourInfo() ? colourInfo()->hasColourLine(line, anti) : false;
00633 }
00634
00639 bool hasAntiColourLine(tcColinePtr line) const {
00640 return hasColourLine(line, true);
00641 }
00642
00646 bool coloured() const { return data().coloured(); }
00647
00651 bool hasColour(bool anti = false) const { return data().hasColour(anti); }
00652
00656 bool hasAntiColour() const { return data().hasAntiColour(); }
00657
00661 tcCBPtr colourInfo() const {
00662 return hasRep() ? rep().theColourInfo : CBPtr();
00663 }
00664
00668 tCBPtr colourInfo() {
00669 if ( !rep().theColourInfo ) rep().theColourInfo = new_ptr(ColourBase());
00670 return rep().theColourInfo;
00671 }
00672
00676 void colourInfo(tCBPtr c) {
00677 rep().theColourInfo = c;
00678 }
00679
00686 template <typename Iterator>
00687 typename std::iterator_traits<Iterator>::value_type
00688 colourNeighbour(Iterator first, Iterator last, bool anti = false) const;
00689
00695 template <typename Iterator>
00696 typename std::iterator_traits<Iterator>::value_type
00697 antiColourNeighbour(Iterator first, Iterator last) const {
00698 return colourNeighbour(first, last, true);
00699 }
00700
00706 void colourNeighbour(tPPtr, bool anti = false);
00707
00712 void antiColourNeighbour(tPPtr p) { colourNeighbour(p, true); }
00713
00718 void antiColourConnect(tPPtr neighbour) {
00719 colourConnect(neighbour, true);
00720 }
00721
00727 void colourConnect(tPPtr neighbour, bool anti = false) {
00728 colourNeighbour(neighbour, anti);
00729 }
00730
00736 tPPtr incomingColour(bool anti = false) const;
00737
00743 tPPtr incomingAntiColour() const { return incomingColour(true); }
00744
00750 void incomingColour(tPPtr p, bool anti = false) { p->outgoingColour(this, anti); }
00751
00756 void incomingAntiColour(tPPtr p) { p->outgoingColour(this, true); }
00757
00763 tPPtr outgoingColour(bool anti = false) const;
00769 tPPtr outgoingAntiColour() const { return outgoingColour(true); }
00770
00776 void outgoingColour(tPPtr, bool anti = false);
00777
00782 void outgoingAntiColour(tPPtr p) { outgoingColour(p, true); }
00783
00787 void colourFlow(tPPtr child, bool anti = false) {
00788 outgoingColour(child, anti);
00789 }
00790
00794 void antiColourFlow(tPPtr child) { colourFlow(child, true); }
00795
00799 void resetColour() {
00800 if ( hasColourInfo() ) rep().theColourInfo = CBPtr();
00801 }
00802
00804
00810 tcSpinPtr spinInfo() const {
00811 return hasRep() ? rep().theSpinInfo : SpinPtr();
00812 }
00813
00817 tSpinPtr spinInfo() {
00818 return hasRep() ? rep().theSpinInfo : SpinPtr();
00819 }
00820
00824 void spinInfo(tSpinPtr s) { rep().theSpinInfo = s; }
00826
00832 const EIVector & getInfo() const {
00833 static const EIVector null;
00834 return hasRep() ? rep().theExtraInfo : null;
00835 }
00836
00840 EIVector & getInfo() { return rep().theExtraInfo; }
00842
00843 public:
00844
00851 bool hasRep() const { return theRep; }
00852
00857 void initFull();
00858
00860
00861 public:
00862
00868 void persistentOutput(PersistentOStream &) const;
00869
00873 void persistentInput(PersistentIStream &, int);
00874
00876
00881 ostream & print(ostream & os, tcStepPtr step = tcStepPtr()) const;
00882
00886 template <typename Iterator>
00887 static void PrintParticles(ostream & os, Iterator first, Iterator last,
00888 tcStepPtr step = tcStepPtr());
00889
00893 template <typename Cont>
00894 static inline void PrintParticles(ostream & os, const Cont & c,
00895 tcStepPtr step = tcStepPtr()) {
00896 PrintParticles(os, c.begin(), c.end(), step);
00897 }
00898
00902 static void Init();
00903
00908 static string outputFormat;
00909
00910 private:
00911
00915 virtual PPtr clone() const;
00916
00923 virtual void rebind(const EventTranslationMap &);
00924
00928 void number(int n) { rep().theNumber = n; }
00929
00933 void removeChild(tPPtr c) {
00934 if ( hasRep() )
00935 rep().theChildren.erase(remove(rep().theChildren.begin(),
00936 rep().theChildren.end(), c),
00937 rep().theChildren.end());
00938 }
00939
00943 void removeParent(tPPtr p) {
00944 if ( hasRep() )
00945 rep().theParents.erase(remove(rep().theParents.begin(),
00946 rep().theParents.end(), p),
00947 rep().theParents.end());
00948 }
00949
00953 void mass(Energy m) { theMomentum.setMass(m); }
00954
00958 void lifeTime(Length t) { rep().theLifeLength.setTau(t); }
00959
00964 ParticleRep & rep() {
00965 if ( !hasRep() ) initFull();
00966 return *theRep;
00967 }
00968
00973 const ParticleRep & rep() const {
00974 static const ParticleRep null;
00975 return hasRep() ? *theRep : null;
00976 }
00977
00981 cEventPDPtr theData;
00982
00986 Lorentz5Momentum theMomentum;
00987
00992 ParticleRep * theRep;
00993
00994 public:
00995
01002 struct ParticleRep {
01003
01007 ParticleRep() : theScale(-1.0*GeV2), theNumber(0) {}
01008
01012 ParticleRep(const ParticleRep &);
01013
01017 tParticleVector theParents;
01018
01022 ParticleVector theChildren;
01023
01027 tPPtr thePrevious;
01028
01032 PPtr theNext;
01033
01038 tDMPtr theDecayMode;
01039
01043 tStepPtr theBirthStep;
01044
01048 LorentzPoint theVertex;
01049
01053 Lorentz5Distance theLifeLength;
01054
01058 Energy2 theScale;
01059
01063 int theNumber;
01064
01068 CBPtr theColourInfo;
01069
01073 SpinPtr theSpinInfo;
01074
01078 EIVector theExtraInfo;
01079
01080 };
01081
01082 public:
01083
01088 virtual void debugme() const;
01089
01090 protected:
01091
01096 Particle() : theRep(0) {}
01097
01102 friend class ClassTraits<Particle>;
01103
01104 private:
01105
01109 Particle & operator=(const Particle &);
01110
01114 static ClassDescription<Particle> initParticle;
01115
01116 };
01117
01121 ostream & operator<<(ostream &, const Particle &);
01122
01123
01128 template <>
01129 struct BaseClassTrait<Particle,1>: public ClassTraitsType {
01131 typedef EventRecordBase NthBase;
01132 };
01133
01136 template <>
01137 struct ClassTraits<Particle>: public ClassTraitsBase<Particle> {
01139 static string className() { return "ThePEG::Particle"; }
01141 static TPtr create() { return TPtr::Create(Particle()); }
01142 };
01143
01146 }
01147
01148 #ifndef ThePEG_TEMPLATES_IN_CC_FILE
01149 #include "Particle.tcc"
01150 #endif
01151
01152 #endif