#ifndef METOOLS_Main_Spin_Structure_H #define METOOLS_Main_Spin_Structure_H #include "METOOLS/Main/Polarization_Index.H" #include "ATOOLS/Math/MyComplex.H" #include "ATOOLS/Phys/Particle.H" #include "ATOOLS/Math/Matrix.H" #include "ATOOLS/Org/Message.H" #include #include #include "ATOOLS/Org/Exception.H" namespace METOOLS { bool SortByFirst(const std::pair p1, const std::pair p2); template class Spin_Structure : public std::vector, public Polarization_Index { protected: size_t GetNumber(std::vector >& spins) const { sort(spins.begin(),spins.end(),SortByFirst); if(spins.size()!=m_spins.size()) { msg_Error()<this->size()) { msg_Error()< "<size()<& spins, const Value& value): Polarization_Index(spins) { this->resize(m_n, value); } Spin_Structure(const ATOOLS::Flavour_Vector& flavs, const Value& value) { m_spins = std::vector(flavs.size()); m_n=1; for(size_t i=0;iresize(m_n,value); } Spin_Structure(const ATOOLS::Flavour_Vector& flavs, const std::vector& indices) { m_spins = std::vector(indices.size()); m_n=1; for(size_t i=0;iresize(m_n); } /*! \brief Constructor ATOOLS::Particles' flavours determine the number of spin combinations of each node. */ Spin_Structure(const ATOOLS::Particle_Vector& particles) { m_spins = std::vector(particles.size()); m_n=1; for(size_t i=0;iFlav().IsVector() && particles[i]->Flav().IsMassive()==0) m_spins[i] = 2; else m_spins[i] = particles[i]->Flav().IntSpin()+1; m_n*=m_spins[i]; } this->resize(m_n); } ~Spin_Structure() {} inline size_t GetNumber(const std::vector &spins) const { return (*this)(spins); } inline std::vector GetSpinCombination(size_t number) const { return (*this)(number); } /*! \brief Inserts value at the right position determined by GetNumber. */ void Insert(Value value, std::vector >& spins) { (*this)[GetNumber(spins)]=value; } void Insert(Value value, const std::vector& spins) { (*this)[GetNumber(spins)]=value; } void Add(Value value, std::vector >& spins) { (*this)[GetNumber(spins)]=value; } /*! \brief Inserts value at the given position. */ void Insert(Value value, size_t index) { (*this)[index]=value; } Value Get(const std::vector& spins) const { return (*this)[GetNumber(spins)]; } Value Get(size_t index) const { return (*this)[index]; } void CreateTrivial(Value value) { size_t n = this->size(); this->clear(); this->resize(n,value); } Spin_Structure& operator+= (const Spin_Structure& addend) { for(size_t i=0;isize();i++) { (*this)[i]+=addend[i]; } return *this; } }; template std::ostream& operator<<(std::ostream& ostr, const Spin_Structure& s) { ostr<<" Spin_Structure with "< spins = s.GetSpinCombination(i); for(size_t j=0;j { public: Spin_Amplitudes(const std::vector& spins, const Complex& value); Spin_Amplitudes(const ATOOLS::Flavour_Vector& flavs, const Complex& value); Spin_Amplitudes(const ATOOLS::Flavour_Vector& flavs, const std::vector& indices); Spin_Amplitudes(const ATOOLS::Particle_Vector& particles); virtual ~Spin_Amplitudes(); double SumSquare() const; virtual void Calculate(const ATOOLS::Vec4D_Vector& momenta,bool anti=false); }; /*! \class Spin_Structure \brief Storing objects by spin combination. This class provides methods to access and manipulate arbitrary objects, by specifying the corresponding spin combination. It inherits from STL vector which contains one 'object' for each spin combination. Objects are stored in the @c std::vector base class as follows: Objects are ordered as in this example (where the node part1 has 2 spin combinations, part2 has 1, part3 has 3, part4 has 2): | part1 | part2 | part3 | part4 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 1 | 0 | 3 | 1 | 0 | 1 | 0 | 4 | 0 | 0 | 2 | 0 | 5 | 1 | 0 | 2 | 0 | 6 | 0 | 0 | 0 | 1 | 7 | 1 | 0 | 0 | 1 | 8 | 0 | 0 | 1 | 1 | 9 | 1 | 0 | 1 | 1 | 10 | 0 | 0 | 2 | 1 | 11 | 1 | 0 | 2 | 1 | The polarisation index for each particle corresponds to: - lambda - \f$0 \to \epsilon^+\f$ - \f$1 \to \epsilon^-\f$ - \f$2 \to \epsilon^0\f$ . */ /*! \fn size_t Spin_Structure::GetNumber(const std::vector& spins) const \brief Determine number of given combination in the STL vector. Here, the spins have to be specified in the same order as in m_spins (i.e. as the flavours or particles in the constructor where specified). */ /*! \fn size_t Spin_Structure::GetNumber(std::vector >& spins) const \brief Determine number of given combination in the STL vector. Here, the spins (second int in pair) can be in arbitrary order, as long as the first int in the pair specifies the number in m_spins it belongs to. */ /*! \fn std::vector Spin_Structure::GetSpinCombination(size_t number) const \brief Determine spin combination from number of combination in the vector. The other way around from the GetNumber methods. Useful to traverse through all spin combinations. */ /*! \fn METOOLS::Spin_Structure::~Spin_Structure() \brief Destructor Doesn't do anything, because there are no pointer members. */ /*! \fn Value METOOLS::Spin_Structure::Get(const std::vector& spins) const \brief Retrieves the value from the right position determined by GetNumber. */ /*! \fn vector METOOLS::Spin_Structure::Get(size_t index) const; \brief Retrieves the value from the given position. */ /*! \fn void METOOLS::Spin_Structure::CreateTrivial(Value value) \brief Inserts the given object for all spin combinations. */ } #endif