Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // -*- C++ -*-
0002 //
0003 // SpinInfo.h is a part of ThePEG - Toolkit for HEP Event Generation
0004 // Copyright (C) 2003-2019 Peter Richardson, 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_SpinInfo_H
0010 #define ThePEG_SpinInfo_H
0011 // This is the declaration of the SpinInfo class.
0012 
0013 #include "ThePEG/EventRecord/EventInfoBase.h"
0014 #include "ThePEG/PDT/PDT.h"
0015 #include "ThePEG/Interface/ClassDocumentation.h"
0016 #include "HelicityVertex.h"
0017 
0018 namespace ThePEG {
0019 
0020 /**
0021  *   The SpinInfo is the base class for the spin information for the
0022  *   spin correlation algorithm. The implementations for different spin
0023  *   states inherit from this.
0024  *
0025  *   The class contains pointers to the vertex where the particle is
0026  *   produced and where it decays, together with methods to set/get
0027  *   these.
0028  *
0029  *   There are two flags decayed which store information on the state
0030  *   of the particle.
0031  *
0032  *   The decayed() members provides access to the _decay data member
0033  *   which is true if the spin density matrix required to perform the
0034  *   decay of a timelike particle has been calculated (this would be a
0035  *   decay matrix for a spacelike particle.) This is set by the
0036  *   decay() method which calls a method from the production vertex to
0037  *   calculate this matrix. The decay() method should be called by a
0038  *   decayer which uses spin correlation method before it uses the
0039  *   spin density matrix to calculate the matrix element for the
0040  *   decay.
0041  *
0042  *   The developed() member provides access to the _developed data
0043  *   member which is true if the decay matrix required to perform the
0044  *   decays of the siblings of a particle has been calculated (this
0045  *   would a spin density matrix for a spacelike particle.) This is
0046  *   set by the developed() method which calls a method from the decay
0047  *   vertex to calculate the matrix. The developed() method is called
0048  *   by a DecayHandler which is capable of performing spin
0049  *   correlations after all the unstable particles produced by a
0050  *   decaying particle are decayed.
0051  *
0052  *   Methods are also provided to access the spin density and decay
0053  *   matrices for a particle.
0054  *
0055  * @author Peter Richardson
0056  *
0057  */
0058 class SpinInfo: public EventInfoBase {
0059 
0060 public:
0061 
0062   /**
0063    *  Status for the implementation of spin correlations
0064    */
0065   enum DevelopedStatus {
0066     Undeveloped=0, /**< Not developed. */
0067     Developed=1,   /**< Developed. */
0068     NeedsUpdate=2,  /**< Developed but needs recalculating due to some change. */
0069     StopUpdate=3     /**< Stop recalculating at this spin info. */
0070   };
0071 
0072 public:
0073 
0074   /** @name Standard constructors and destructors. */
0075   //@{
0076   /**
0077    * Default constructor.
0078    */
0079   SpinInfo() 
0080     : _timelike(false), _prodloc(-1), _decayloc(-1), 
0081       _decayed(false), _developed(Undeveloped),
0082       _oldDeveloped(Undeveloped) {}
0083 
0084   /**
0085    * Standard Constructor.
0086    * @param s the spin.
0087    * @param p the production momentum.
0088    * @param time true if the particle is time-like.
0089    */
0090   SpinInfo(PDT::Spin s, 
0091        const Lorentz5Momentum & p = Lorentz5Momentum(), 
0092        bool time = false)
0093     : _timelike(time), _prodloc(-1), _decayloc(-1),
0094       _decayed(false),
0095       _developed(Undeveloped), _oldDeveloped(Undeveloped),
0096       _rhomatrix(s), _Dmatrix(s), _spin(s),
0097       _productionmomentum(p), _currentmomentum(p) {}
0098 
0099   /**
0100    * Copy-constructor.
0101    */
0102   SpinInfo(const SpinInfo &);
0103   //@}
0104 
0105 public:
0106 
0107   /**
0108    * Returns true if the polarization() has been implemented in a
0109    * subclass. This default version returns false.
0110    */
0111   virtual bool hasPolarization() const { return false; }
0112 
0113   /**
0114    * Return the angles of the polarization vector as a pair of
0115    * doubles. first is the polar angle and second is the azimuth
0116    * wrt. the particles direction. This default version of the
0117    * function returns 0,0, and if a subclass implements a proper
0118    * function it should also implement 'hasPolarization()' to return
0119    * true.
0120    */
0121   virtual DPair polarization() const { return DPair(); }
0122 
0123 public:
0124 
0125   /**
0126    * Standard Init function.
0127    */
0128   static void Init();
0129 
0130   /**
0131    * Rebind to cloned objects. If a FermionSpinInfo is cloned together
0132    * with a whole Event and this has pointers to other event record
0133    * objects, these should be rebound to their clones in this
0134    * function.
0135    */
0136   virtual void rebind(const EventTranslationMap & trans);
0137 
0138   /**
0139    * Standard clone method.
0140    */
0141   virtual EIPtr clone() const;
0142 
0143   /**
0144    * Method to handle the delelation
0145    */
0146   void update() const;
0147 
0148   /**
0149    * Perform a lorentz rotation of the spin information
0150    */
0151   virtual void transform(const LorentzMomentum & m, const LorentzRotation & r) {
0152     _currentmomentum = m;
0153     _currentmomentum.transform(r);
0154   }
0155 
0156   /**
0157    *  Reset - Undoes any transformations and calls undecay.
0158    */
0159   virtual void reset() {
0160     _currentmomentum = _productionmomentum;
0161   }
0162   
0163 public:
0164 
0165 
0166   /** @name Access the vertices. */
0167   //@{
0168   /**
0169    * Set the vertex at which the particle was produced.
0170    */
0171   void productionVertex(VertexPtr in) const {
0172     _production=in;
0173     // add to the list of outgoing if timelike
0174     int temp(-1);
0175     if(_timelike) in->addOutgoing(this,temp); 
0176     // or incoming if spacelike
0177     else          in->addIncoming(this,temp);
0178     _prodloc=temp;
0179   }
0180 
0181   /**
0182    * Get the vertex at which the particle was produced.
0183    */
0184   tcVertexPtr productionVertex() const { return _production; }
0185 
0186   /**
0187    * Set the vertex at which the particle decayed or branched.
0188    */
0189   void decayVertex(VertexPtr in) const {
0190     if(in) {
0191       _decay=in;
0192       if(_timelike) {
0193     int temp(-1);
0194     in->addIncoming(this,temp);
0195     _decayloc=temp;
0196     assert(temp==0);
0197       }
0198       else {
0199     int temp(-1);
0200     in->addOutgoing(this,temp);
0201     _decayloc=temp;
0202       }
0203     }
0204     else {
0205       _decay=VertexPtr();
0206       _decayloc=-1;
0207     }
0208   }
0209 
0210   /**
0211    * Get the vertex at which the particle decayed or branched.
0212    */
0213   tcVertexPtr decayVertex() const { return _decay; }
0214   //@}
0215 
0216   /** @name Access information about the associated particle. */
0217   //@{
0218   /**
0219    * Has the particle decayed?
0220    */
0221   bool decayed() const { return _decayed; }
0222 
0223   /**
0224    * Set if the particle has decayed.
0225    */
0226   void decayed(bool b) const { _decayed = b; }
0227 
0228   /**
0229    * Return true if the decay matrix required to perform the decays of
0230    * the siblings of a particle has been calculated.
0231    */
0232   DevelopedStatus developed() const { return _developed; }
0233 
0234   /**
0235    * Calculate the rho matrix for the decay if not already done.
0236    */
0237   void decay(bool recursive=false) const ;
0238 
0239   /**
0240    * Calculate the rho matrix for the decay if not already done.
0241    */
0242   virtual void undecay() const ;
0243 
0244   /**
0245    * Set the developed flag and calculate the D matrix for the decay.
0246    */
0247   void develop() const ;
0248 
0249   /**
0250    *  Needs update
0251    */
0252   void needsUpdate() const {
0253     if(_developed!=NeedsUpdate) _oldDeveloped = _developed;
0254     _developed=NeedsUpdate;
0255   }
0256 
0257   /**
0258    *  Used for an unstable particle to *temporarily* stop
0259    *  redevelop and redecay at that particle
0260    */
0261   void stopUpdate() const {_developed=StopUpdate;}
0262 
0263   /**
0264    * Return 2s+1 for the particle
0265    */
0266   PDT::Spin iSpin() const { return _spin; }
0267 
0268   /**
0269    * Return the momentum of the particle when it was produced.
0270    */
0271   const Lorentz5Momentum & productionMomentum() const {
0272     return _productionmomentum;
0273   }
0274 
0275   /**
0276    *  The current momentum of the particle
0277    */
0278   const Lorentz5Momentum & currentMomentum() const {
0279     return _currentmomentum;
0280   }
0281 
0282   /**
0283    * Return true if particle is timelike (rather than spacelike).
0284    */
0285   bool timelike() const { return _timelike; }
0286   //@}
0287 
0288   /**
0289    *  Access to the locations
0290    */
0291   //@{
0292   /**
0293    *  Production Location
0294    */
0295   int productionLocation() const {return _prodloc;}
0296 
0297   /**
0298    *  Decay Location
0299    */
0300   int decayLocation() const {return _decayloc;}
0301   //@}
0302 
0303 public:
0304 
0305   /** @name Access the rho and D matrices. */
0306   //@{
0307   /**
0308    * Access the rho matrix.
0309    */
0310   RhoDMatrix rhoMatrix() const { return _rhomatrix; }
0311 
0312   /**
0313    * Access the rho matrix.
0314    */
0315   RhoDMatrix & rhoMatrix() { return _rhomatrix; }
0316 
0317   /**
0318    * Access the D matrix.
0319    */
0320   RhoDMatrix DMatrix() const { return _Dmatrix; }
0321 
0322   /**
0323    * Access the D matrix.
0324    */
0325   RhoDMatrix & DMatrix() { return _Dmatrix; }
0326   //@}
0327 
0328 public:
0329 
0330   /**
0331    *  Check if momentum is near to the current momentum
0332    */
0333   bool isNear(const Lorentz5Momentum & p) {
0334     return currentMomentum().isNear(p,_eps);
0335   }
0336 
0337 private:
0338 
0339   /**
0340    * Describe a concrete class without persistent data.
0341    */
0342   static NoPIOClassDescription<SpinInfo> initSpinInfo;
0343 
0344   /**
0345    * Private and non-existent assignment operator.
0346    */
0347   SpinInfo & operator=(const SpinInfo &) = delete;
0348 
0349 private:
0350 
0351   /**
0352    * Set the developed flag and calculate the D matrix for the decay,
0353    * and all decays further up the chain.
0354    */
0355   void redevelop() const ;
0356 
0357   /**
0358    * Recursively recalulate all the rho matrices from the top of the chain
0359    */
0360   void redecay() const ;
0361 
0362 private:
0363 
0364   /**
0365    * Pointer to the production vertex for the particle
0366    */
0367   mutable VertexPtr _production;
0368 
0369   /**
0370    * Pointers to the decay vertex for the particle
0371    */
0372   mutable VertexPtr _decay;
0373 
0374   /**
0375    * Is this is timelike (true) or spacelike (false ) particle?  This
0376    * is used to decide if the particle is incoming or outgoing at the
0377    * production vertex
0378    */
0379   bool _timelike;
0380 
0381   /**
0382    * Location in the hard vertex array at production.
0383    */
0384   mutable int _prodloc;
0385 
0386   /**
0387    * Location in the hard vertex array at decay.
0388    */
0389   mutable int _decayloc;
0390 
0391   /**
0392    * Has the particle been decayed?  (I.e. has the rho matrix for the
0393    * decay been calculated.)
0394    */
0395   mutable bool _decayed;
0396 
0397   /**
0398    * Has the particle been developed?  (I.e. has the D matrix encoding
0399    * the info about the decay been calculated)
0400    */
0401   mutable DevelopedStatus _developed;
0402 
0403   /**
0404    * Has the particle been developed?  (I.e. has the D matrix encoding
0405    * the info about the decay been calculated)
0406    */
0407   mutable DevelopedStatus _oldDeveloped;
0408 
0409   /**
0410    * Storage of the rho matrix.
0411    */
0412   mutable RhoDMatrix _rhomatrix;
0413 
0414   /**
0415    * Storage of the decay matrix
0416    */
0417   mutable RhoDMatrix _Dmatrix;
0418 
0419   /**
0420    * The spin of the particle
0421    */
0422   PDT::Spin _spin;
0423 
0424   /**
0425    * Momentum of the particle when it was produced
0426    */
0427   Lorentz5Momentum _productionmomentum;
0428 
0429   /**
0430    * Momentum of the particle when it decayed
0431    */
0432   mutable Lorentz5Momentum _decaymomentum;
0433   
0434   /**
0435    * Current momentum of the particle
0436    */
0437   Lorentz5Momentum _currentmomentum;
0438 
0439   /**
0440    *  A small energy for comparing momenta to check if Lorentz Transformations
0441    *  should be performed
0442    */
0443   static const double _eps;
0444 };
0445 
0446 }
0447 
0448 
0449 namespace ThePEG {
0450 
0451 /** @cond TRAITSPECIALIZATIONS */
0452 
0453 /**
0454  * This template specialization informs ThePEG about the base class of
0455  * SpinInfo.
0456  */
0457 template <>
0458 struct BaseClassTrait<ThePEG::SpinInfo,1>: public ClassTraitsType {
0459   /** Typedef of the base class of SpinInfo. */
0460   typedef EventInfoBase NthBase;
0461 };
0462 
0463 /**
0464  * This template specialization informs ThePEG about the name of the
0465  * SpinInfo class and the shared object where it is defined.
0466  */
0467 template <>
0468 struct ClassTraits<ThePEG::SpinInfo>
0469   : public ClassTraitsBase<ThePEG::SpinInfo> {
0470   /**
0471    * Return the class name.
0472    */
0473   static string className() { return "ThePEG::SpinInfo"; }
0474 };
0475 
0476 /** @endcond */
0477 
0478 }
0479 
0480 #endif /* ThePEG_SpinInfo_H */