Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-19 09:10:07

0001 #ifndef METOOLS_Main_Spin_Structure_H
0002 #define METOOLS_Main_Spin_Structure_H
0003 
0004 #include "METOOLS/Main/Polarization_Index.H"
0005 #include "ATOOLS/Math/MyComplex.H"
0006 #include "ATOOLS/Phys/Particle.H"
0007 #include "ATOOLS/Math/Matrix.H"
0008 #include "ATOOLS/Org/Message.H"
0009 #include <algorithm>
0010 #include <iomanip>
0011 #include "ATOOLS/Org/Exception.H"
0012 
0013 namespace METOOLS
0014 {
0015   bool SortByFirst(const std::pair<int,int> p1, const std::pair<int,int> p2);
0016 
0017   template<class Value>
0018   class Spin_Structure : public std::vector<Value>, public Polarization_Index {
0019   protected:
0020     size_t GetNumber(std::vector<std::pair<int,int> >& spins) const
0021     {
0022       sort(spins.begin(),spins.end(),SortByFirst);
0023       
0024       if(spins.size()!=m_spins.size()) {
0025     msg_Error()<<METHOD<<" Error: wrong size of spin std::vector."<<std::endl;
0026         abort();
0027       }
0028       int mult(1);
0029       size_t num(0);
0030       for(size_t i=0; i<spins.size(); i++) {
0031     num += mult * spins[i].second;
0032     mult *= m_spins[i];
0033       }
0034       if(num>this->size()) {
0035     msg_Error()<<METHOD<<" Error: tried to access value out of bounce. "
0036       <<"num="<<num<<" > "<<this->size()<<std::endl;
0037         abort();
0038       }
0039       return num;
0040     }
0041 
0042   public:
0043     Spin_Structure() {}
0044     Spin_Structure(const std::vector<int>& spins, const Value& value):
0045       Polarization_Index(spins)
0046     {
0047       this->resize(m_n, value);
0048     }
0049     
0050     Spin_Structure(const ATOOLS::Flavour_Vector& flavs, const Value& value)
0051     {
0052       m_spins = std::vector<int>(flavs.size());
0053       m_n=1;
0054       for(size_t i=0;i<flavs.size();i++) {
0055         if(flavs[i].IsVector() && flavs[i].IsMassive()==0) m_spins[i] = 2;
0056         else m_spins[i] = flavs[i].IntSpin()+1;
0057     m_n*=m_spins[i];
0058       }
0059       this->resize(m_n,value);
0060     }
0061     
0062     Spin_Structure(const ATOOLS::Flavour_Vector& flavs,
0063                    const std::vector<int>& indices)
0064     {
0065       m_spins = std::vector<int>(indices.size());
0066 
0067       m_n=1;
0068       for(size_t i=0;i<indices.size();i++) {
0069         if(flavs[indices[i]].IsVector() && flavs[indices[i]].IsMassive()==0)
0070           m_spins[i] = 2;
0071         else m_spins[i] = flavs[indices[i]].IntSpin()+1;
0072     m_n*=m_spins[i];
0073       }
0074       this->resize(m_n);
0075     }
0076 
0077     /*!
0078       \brief Constructor
0079 
0080       ATOOLS::Particles' flavours determine the number of spin combinations of each node.
0081     */
0082     Spin_Structure(const ATOOLS::Particle_Vector& particles)
0083     {
0084       m_spins = std::vector<int>(particles.size());
0085 
0086       m_n=1;
0087       for(size_t i=0;i<particles.size();i++) {
0088         if(particles[i]->Flav().IsVector() && particles[i]->Flav().IsMassive()==0) m_spins[i] = 2;
0089         else m_spins[i] = particles[i]->Flav().IntSpin()+1;
0090     m_n*=m_spins[i];
0091       }
0092       this->resize(m_n);
0093     }
0094     
0095     ~Spin_Structure() {}
0096 
0097     inline size_t GetNumber(const std::vector<int> &spins) const { return (*this)(spins); }
0098 
0099     inline std::vector<int> GetSpinCombination(size_t number) const { return (*this)(number); }
0100 
0101     /*!
0102       \brief Inserts value at the right position determined by GetNumber.
0103     */
0104     void    Insert(Value value, std::vector<std::pair<int,int> >& spins)
0105     {
0106       (*this)[GetNumber(spins)]=value;
0107     }
0108 
0109     void    Insert(Value value, const std::vector<int>& spins)
0110     {
0111       (*this)[GetNumber(spins)]=value;
0112     }
0113 
0114     void    Add(Value value, std::vector<std::pair<int,int> >& spins)
0115     {
0116       (*this)[GetNumber(spins)]=value;
0117     }
0118 
0119     /*!
0120       \brief Inserts value at the given position.
0121     */
0122     void    Insert(Value value, size_t index)
0123     {
0124       (*this)[index]=value;
0125     }
0126 
0127     Value   Get(const std::vector<int>& spins) const
0128     {
0129       return (*this)[GetNumber(spins)];
0130     }
0131     
0132     Value   Get(size_t index) const
0133     {
0134       return (*this)[index];
0135     }
0136 
0137     void    CreateTrivial(Value value)
0138     {
0139       size_t n = this->size();
0140       this->clear();
0141       this->resize(n,value);
0142     }
0143 
0144     Spin_Structure<Value>& operator+= (const Spin_Structure<Value>& addend)
0145     {
0146       for(size_t i=0;i<this->size();i++) {
0147     (*this)[i]+=addend[i];
0148       }
0149       return *this;
0150     }
0151   };
0152 
0153   template<class Value>
0154   std::ostream& operator<<(std::ostream& ostr, const Spin_Structure<Value>& s) {
0155     ostr<<"   Spin_Structure with "<<s.size()<<" spin combinations:"<<std::endl;
0156     for(size_t i=0;i<s.size();i++) {
0157       ostr<<std::setw(3)<<i;
0158       std::vector<int> spins = s.GetSpinCombination(i);
0159       for(size_t j=0;j<spins.size();j++) {
0160         ostr<<std::setw(8)<<spins[j]<<" | ";
0161       }
0162       ostr<<s[i]<<std::endl;
0163     }
0164     return ostr;
0165   }
0166 
0167   class Spin_Amplitudes : public Spin_Structure<Complex> {
0168   public:
0169     Spin_Amplitudes(const std::vector<int>& spins, const Complex& value);
0170     Spin_Amplitudes(const ATOOLS::Flavour_Vector& flavs, const Complex& value);
0171     Spin_Amplitudes(const ATOOLS::Flavour_Vector& flavs,
0172                     const std::vector<int>& indices);
0173     Spin_Amplitudes(const ATOOLS::Particle_Vector& particles);
0174     virtual ~Spin_Amplitudes();
0175     double  SumSquare() const;
0176     virtual void Calculate(const ATOOLS::Vec4D_Vector& momenta,bool anti=false);
0177   };
0178 
0179   /*! 
0180     \class Spin_Structure
0181     \brief Storing objects by spin combination.
0182     
0183     This class provides methods to access and manipulate arbitrary objects, by
0184     specifying the corresponding spin combination. It inherits from STL vector
0185     which contains one 'object' for each spin combination.
0186 
0187     Objects are stored in the @c std::vector base class as follows:
0188     
0189     Objects are ordered as in this example (where the node part1 has
0190     2 spin combinations, part2 has 1, part3 has 3, part4 has 2):
0191         |  part1 |    part2 |    part3 |    part4 |
0192       0 |      0 |        0 |        0 |        0 |
0193       1 |      1 |        0 |        0 |        0 |
0194       2 |      0 |        0 |        1 |        0 |
0195       3 |      1 |        0 |        1 |        0 |
0196       4 |      0 |        0 |        2 |        0 |
0197       5 |      1 |        0 |        2 |        0 |
0198       6 |      0 |        0 |        0 |        1 |
0199       7 |      1 |        0 |        0 |        1 |
0200       8 |      0 |        0 |        1 |        1 |
0201       9 |      1 |        0 |        1 |        1 |
0202      10 |      0 |        0 |        2 |        1 |
0203      11 |      1 |        0 |        2 |        1 |
0204 
0205      The polarisation index for each particle corresponds to:
0206       - <var>lambda</var>
0207         - \f$0 \to \epsilon^+\f$
0208         - \f$1 \to \epsilon^-\f$
0209         - \f$2 \to \epsilon^0\f$
0210         .
0211   */
0212 
0213   /*!
0214     \fn size_t Spin_Structure::GetNumber(const std::vector<int>& spins) const
0215     \brief Determine number of given combination in the STL vector.
0216 
0217     Here, the spins have to be specified in the same order as in m_spins (i.e.
0218     as the flavours or particles in the constructor where specified).
0219   */
0220 
0221   /*!
0222     \fn size_t Spin_Structure::GetNumber(std::vector<std::pair<int,int> >& spins) const
0223     \brief Determine number of given combination in the STL vector.
0224 
0225     Here, the spins (second int in pair) can be in arbitrary order, as long as
0226     the first int in the pair specifies the number in m_spins it belongs to.
0227   */
0228 
0229   /*!
0230     \fn std::vector<int> Spin_Structure::GetSpinCombination(size_t number) const
0231     \brief Determine spin combination from number of combination in the vector.
0232 
0233     The other way around from the GetNumber methods. Useful to
0234     traverse through all spin combinations.
0235   */
0236 
0237   /*!
0238     \fn METOOLS::Spin_Structure<Value>::~Spin_Structure()
0239     \brief Destructor
0240 
0241     Doesn't do anything, because there are no pointer members.
0242   */
0243 
0244   /*!
0245     \fn Value METOOLS::Spin_Structure<Value>::Get(const std::vector<int>& spins) const
0246     \brief Retrieves the value from the right position determined by GetNumber.
0247   */
0248 
0249   /*!
0250     \fn vector<Complex> METOOLS::Spin_Structure<Value>::Get(size_t index) const;
0251     \brief Retrieves the value from the given position.
0252   */
0253 
0254   /*!
0255     \fn void METOOLS::Spin_Structure<Value>::CreateTrivial(Value value)
0256     \brief Inserts the given object for all spin combinations.
0257   */
0258 
0259 }
0260 
0261 
0262 #endif