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
0079
0080
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
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
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
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 }
0260
0261
0262 #endif