|
|
|||
File indexing completed on 2026-08-06 09:38:32
0001 // -*- C++ -*- 0002 // 0003 // UtilityBase.h is a part of ThePEG - Toolkit for HEP Event Generation 0004 // Copyright (C) 1999-2019 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_UtilityBase_H 0010 #define ThePEG_UtilityBase_H 0011 0012 #include "ThePEG/Config/ThePEG.h" 0013 #include "ThePEG/EventRecord/ParticleTraits.h" 0014 #include "ThePEG/Utilities/Triplet.h" 0015 0016 namespace ThePEG { 0017 0018 /** 0019 * UtilityBase is a base class implementing a number of static utility 0020 * functions. It should be used as a base class to give acces to these 0021 * functions to a class. A class can safely multiply inherit from this 0022 * class as it only contains static functions. 0023 */ 0024 struct UtilityBase { 0025 0026 /** 0027 * Sums the four-momentum of given container. The class 0028 * <code>Cont::value_type</code> must be of a type <code>T</code> 0029 * for which <code>ParticleTraits<T>::momentum(const T&)</code> is 0030 * implemented correctly. 0031 */ 0032 template <typename Cont> 0033 static LorentzMomentum sumMomentum(const Cont & c) { 0034 return sumMomentum(c.begin(), c.end()); 0035 } 0036 0037 /** 0038 * Sums the four-momentum of the entries between first and last. The 0039 * class <code>Iterator::value_type</code> must be of a type 0040 * <code>T</code> for which <code>ParticleTraits<T>::momentum(const 0041 * T&)</code> is implemented correctly. 0042 */ 0043 template <typename Iterator> 0044 static LorentzMomentum sumMomentum(Iterator first, Iterator last) { 0045 LorentzMomentum sum; 0046 typedef typename std::iterator_traits<Iterator>::value_type PType; 0047 typedef ParticleTraits<PType> Traits; 0048 0049 while ( first != last ) sum += Traits::momentum(*first++); 0050 return sum; 0051 } 0052 0053 /** 0054 * Transform the entries between \a first and \a last. The class 0055 * <code>Iterator::value_type</code> must be of a type 0056 * <code>T</code> for which <code>ParticleTraits<T>::momentum(const 0057 * T&)</code> is implemented correctly. 0058 */ 0059 template <typename Iterator> 0060 static void transform(Iterator first, Iterator last, 0061 const LorentzRotation & boost) { 0062 typedef typename std::iterator_traits<Iterator>::value_type PType; 0063 typedef ParticleTraits<PType> Traits; 0064 0065 while ( first != last ) Traits::transform(*first++, boost); 0066 } 0067 0068 /** 0069 * Transform the entries in a container \a cont. The class 0070 * <code>Cont::value_type</code> must be of a type <code>T</code> 0071 * for which <code>ParticleTraits<T>::momentum(const T&)</code> is 0072 * implemented correctly. 0073 */ 0074 template <typename Cont> 0075 static void transform(Cont & cont, const LorentzRotation & boost) { 0076 transform(cont.begin(), cont.end(), boost); 0077 } 0078 0079 /** 0080 * Boost the two objects in the pair to their CM system. Also rotate 0081 * so that the first is along the z-axis. The class 0082 * <code>PType</code> must have 0083 * <code>ParticleTraits<PType>::momentum(const PType&)</code> and 0084 * <code>ParticleTraits<PType>::transform(PType&, const 0085 * LorentzRotation&)</code> implemented correctly. 0086 */ 0087 template <typename PType> 0088 static LorentzRotation boostToCM(const pair<PType,PType> & pp); 0089 0090 /** 0091 * Boost the three objects in the Triplet to their CM system. Also 0092 * rotate so that the first is along the z-axis and the second is in 0093 * the x-z plane with positive x. The class <code>PType</code> must 0094 * have <code>ParticleTraits<PType>::momentum(const PType&)</code> 0095 * and <code>ParticleTraits<PType>::transform(PType&, const 0096 * LorentzRotation&)</code> implemented correctly. 0097 */ 0098 template <typename PType> 0099 static LorentzRotation boostToCM(const Triplet<PType,PType,PType> & pt); 0100 0101 /** 0102 * Obtain the LorentzRotation needed to boost the two objects in the 0103 * pair to their CM system. Also rotate the LorentzRotation so that 0104 * the first is along the z-axis. The class <code>PType</code> must 0105 * have <code>ParticleTraits<PType>::momentum(const PType&)</code> 0106 * implemented correctly. 0107 */ 0108 template <typename PType> 0109 static LorentzRotation getBoostToCM(const pair<PType,PType> & pp); 0110 0111 /** 0112 * Obtain the LorentzRotation needed to boost the three objects in 0113 * the Triplet to their CM system. Also rotate the LorentzRotation 0114 * so that the first is along the z-axis and the secons i in the x-z 0115 * plane with positive x. The class <code>PType</code> 0116 * must have <code>ParticleTraits<PType>::momentum(const 0117 * PType&)</code> implemented correctly. 0118 */ 0119 template <typename PType> 0120 static LorentzRotation getBoostToCM(const Triplet<PType,PType,PType> & pt); 0121 0122 /** 0123 * Get the inverse boost as compared to getBoostToCM. 0124 */ 0125 template <typename PType> 0126 static LorentzRotation getBoostFromCM(const pair<PType,PType> & pp); 0127 0128 /** 0129 * Get the inverse boost as compared to getBoostToCM. 0130 */ 0131 template <typename PType> 0132 static LorentzRotation getBoostFromCM(const Triplet<PType,PType,PType> & pt); 0133 0134 /** 0135 * Boost the entries between fisrt and last into their CM system. 0136 * The class <code>Iterator::value_type</code> must be of a type 0137 * <code>T</code> for which <code>ParticleTraits<T>::momentum(const 0138 * T&)</code> and <code>ParticleTraits<T>::transform(T&, const 0139 * LorentzRotation&)</code> are implemented correctly. 0140 */ 0141 template <typename Iterator> 0142 static LorentzRotation boostToCM(Iterator first, Iterator last) { 0143 return boostToCM(first, last, last, last); 0144 } 0145 0146 /** 0147 * Boost the entries between fisrt and last into their CM system. If 0148 * zAxis != last, also rotate the entries so that zAxis becomes 0149 * paralell to the z-axis. The class 0150 * <code>Iterator::value_type</code> must be of a type 0151 * <code>T</code> for which <code>ParticleTraits<T>::momentum(const 0152 * T&)</code> and <code>ParticleTraits<T>::transform(T&, const 0153 * LorentzRotation&)</code> are implemented correctly. 0154 */ 0155 template <typename Iterator> 0156 static LorentzRotation boostToCM(Iterator first, Iterator last, Iterator zAxis) { 0157 return boostToCM(first, last, zAxis, last); 0158 } 0159 0160 /** 0161 * Boost the entries between fisrt and last into their CM system. If 0162 * zAxis != last, also rotate the entries so that zAxis becomes 0163 * paralell to the z-axis. Also, if xzPlane != last, rotate the 0164 * entries so that xzPlane is placed in the xz-plane. The class 0165 * <code>Iterator::value_type</code> must be of a type 0166 * <code>T</code> for which <code>ParticleTraits<T>::momentum(const 0167 * T&)</code> and <code>ParticleTraits<T>::transform(T&, const 0168 * LorentzRotation&)</code> are implemented correctly. 0169 */ 0170 template <typename Iterator> 0171 static LorentzRotation boostToCM(Iterator first, Iterator last, 0172 Iterator zAxis, Iterator xzPlane); 0173 0174 /** 0175 * Rotate p to the z-axis and boost it to its CMS, then boost it 0176 * along the z-axis and rotate it so that it ends up with momentum 0177 * q. If p is massless - simply set its momentum. The class 0178 * <code>PType</code> must have 0179 * <code>ParticleTraits<PType>::momentum(const PType&)</code> 0180 * implemented correctly. 0181 */ 0182 template <typename PType> 0183 static void setMomentum(PType & p, const Momentum3 & q); 0184 0185 /** 0186 * Boost p along the z-axis and rotate it so that, if it was 0187 * previously at rest, it ends up with momentum q. If p is massless 0188 * - simply set its momentum to q. The class 0189 * <code>PType</code> must have 0190 * <code>ParticleTraits<PType>::momentum(const PType&)</code> 0191 * implemented correctly. 0192 */ 0193 template <typename PType> 0194 static void setMomentumFromCMS(PType & p, const Momentum3 & q); 0195 0196 /** 0197 * Rotate the range of particles so their sum is along z-axis and 0198 * boost them to their CMS, then boost them along the z-axis and 0199 * rotate them so that they end up with total momentum q. The class 0200 * <code>Iter::value_type</code> must be of a type <code>T</code> 0201 * for which <code>ParticleTraits<T>::momentum(const T&)</code> and 0202 * <code>ParticleTraits<T>::transform(T&, const 0203 * LorentzRotation&)</code> are implemented correctly. 0204 */ 0205 template <typename Iter> 0206 static void setMomentum(Iter first, Iter last, const Momentum3 & q); 0207 0208 /** 0209 * Rotate the range of particles so their sum is along z-axis then 0210 * boost them along the z-axis and rotate them so that they end up 0211 * with total momentum q. If a single boost does not succeed to 0212 * obtain the required precision within eps times the total energy, 0213 * the boost is redone. The class <code>Iter::value_type</code> must 0214 * be of a type <code>T</code> for which 0215 * <code>ParticleTraits<T>::momentum(const T&)</code> and 0216 * <code>ParticleTraits<T>::transform(T&, const 0217 * LorentzRotation&)</code> are implemented correctly. 0218 */ 0219 template <typename Iter> 0220 static void setMomentum(Iter first, Iter last, 0221 const Momentum3 & q, double eps); 0222 0223 /** 0224 * Boost the range of particles along the z-axis and rotate them so 0225 * that, if they were previously in their rest frame, they end up 0226 * with total momentum q. The class <code>Iter::value_type</code> must 0227 * be of a type <code>T</code> for which 0228 * <code>ParticleTraits<T>::momentum(const T&)</code> and 0229 * <code>ParticleTraits<T>::transform(T&, const 0230 * LorentzRotation&)</code> are implemented correctly. 0231 * @param first iterator pointing to the first particle in the range. 0232 * @param last iterator indicating the end of the range. 0233 * @param m2 the invariant mass squared of the particles. 0234 * @param q final summed momentum of the particles. 0235 */ 0236 template <typename Iter> 0237 static void setMomentumFromCMS(Iter first, Iter last, 0238 Energy2 m2, const Momentum3 & q); 0239 0240 /** 0241 * Return the transformation needed to rotate \a p to the z-axis and 0242 * boost it to its CMS, then boost it along the z-axis and rotate it 0243 * so that it ends up with momentum \a q. The class 0244 * <code>PType</code> must have 0245 * <code>ParticleTraits<PType>::momentum(const PType&)</code> 0246 * implemented correctly. <b>Warning</b> This function only works 0247 * properly if \a p has a well defined direction in both polar and 0248 * azimuth angles. 0249 * \deprecated{Use getTransformToMomentum() instead.} 0250 */ 0251 template <typename PType> 0252 static LorentzRotation transformToMomentum(const PType & p, 0253 const Momentum3 & q) { 0254 typedef ParticleTraits<PType> Traits; 0255 LorentzMomentum q4(q, sqrt(q.mag2() + Traits::momentum(p).m2())); 0256 return transformToMomentum(p, q4); 0257 } 0258 0259 /** 0260 * Return the transformation needed to rotate \a p to the z-axis and 0261 * boost it to its CMS, then boost it along the z-axis and rotate it 0262 * so that it ends up with momentum \a q. The class <code>PType</code> 0263 * must have <code>ParticleTraits<PType>::momentum(const 0264 * PType&)</code> implemented correctly. <b>Warning</b> This 0265 * function only works properly if \a p has a well defined direction 0266 * in both polar and azimuth angles. 0267 * \deprecated{Use getTransformToMomentum() instead.} 0268 */ 0269 template <typename PType> 0270 static LorentzRotation transformToMomentum(const PType & p, 0271 const LorentzMomentum & q) { 0272 return transformFromCMS(q)*transformToCMS(p); 0273 } 0274 0275 /** 0276 * Return a transformation appropriate for transforming \a p to have 0277 * the momentum \a q. The transformation is done so that the 0278 * auxiliary vector \a k is left unchanged. 0279 */ 0280 template <typename PType> 0281 static LorentzRotation getTransformToMomentum(const PType & p, 0282 const LorentzMomentum & q, 0283 const LorentzMomentum & k) { 0284 typedef ParticleTraits<PType> Traits; 0285 LorentzMomentum k0 = Traits::momentum(p) - k; 0286 LorentzMomentum k1 = Traits::momentum(q) - k; 0287 return getBoostFromCM(make_pair(k1, k))*getBoostToCM(make_pair(k0, k)); 0288 } 0289 0290 /** 0291 * Return a transformation appropriate for transforming \a p to have 0292 * the momentum \a q. The transformation is done so that the 0293 * auxiliary vector \a k is left unchanged. 0294 */ 0295 template <typename PType> 0296 static LorentzRotation getTransformToMomentum(const PType & p, 0297 const Momentum3 & q, 0298 const LorentzMomentum & k) { 0299 typedef ParticleTraits<PType> Traits; 0300 LorentzMomentum q4(q, sqrt(q.mag2() + Traits::momentum(p).m2())); 0301 return getTransformToMomentum(p, q4, k); 0302 } 0303 0304 /** 0305 * Create a rotation corresponding to transforming p to its current 0306 * value from its CMS by first boosting along the z-axis and then 0307 * rotating. The class <code>LV</code> must have methods 0308 * <code>rho()</code> and <code>e()</code>. 0309 */ 0310 template <typename LV> 0311 static LorentzRotation transformFromCMS(const LV & p); 0312 0313 /** 0314 * Create a rotation corresponding to transforming sum to its 0315 * current value from its CMS, with zAxis along the z-axis in that 0316 * CMS frame. The class <code>LV</code> must have methods 0317 * <code>rho()</code>, <code>phi()</code> <code>theta()</code> and 0318 * <code>e()</code>. 0319 */ 0320 template <typename LV> 0321 static LorentzRotation transformFromCMS(const LV & sum, LV zAxis); 0322 0323 /** 0324 * Create a rotation corresponding to transforming sum to its 0325 * current value from its CMS, with zAxis along the z-axis and 0326 * xyPlane in the x-y plane in that CMS frame. The class 0327 * <code>LV</code> must have methods <code>rho()</code>, 0328 * <code>phi()</code> <code>theta()</code> and <code>e()</code>. 0329 */ 0330 template <typename LV> 0331 static LorentzRotation transformFromCMS(const LV & sum, 0332 const LV & zAxis, LV xyPlane); 0333 0334 /** 0335 * Create a rotation which would transform sum to its CMS frame with 0336 * zAxis along the z-axis in that frame. The class <code>LV</code> 0337 * must have methods <code>rho()</code>, <code>phi()</code> 0338 * <code>theta()</code> and <code>e()</code>. 0339 */ 0340 template <typename LV> 0341 static LorentzRotation transformToCMS(const LV & sum, LV zAxis); 0342 0343 /** 0344 * Create a rotation which would transform sum to its CMS frame 0345 * first rotating it to the z-axis and then boost it along the 0346 * z-axis. The class <code>LV</code> must have methods 0347 * <code>rho()</code>, <code>phi()</code> <code>theta()</code> and 0348 * <code>e()</code>. 0349 */ 0350 template <typename LV> 0351 static LorentzRotation transformToCMS(const LV & p); 0352 0353 /** 0354 * Create a rotation which would transform sum to its CMS frame with 0355 * zAxis along the z-axis and xyPlane in the x-y plane in that 0356 * frame. The class <code>LV</code> must have methods 0357 * <code>rho()</code>, <code>phi()</code> <code>theta()</code> and 0358 * <code>e()</code>. 0359 */ 0360 template <typename LV> 0361 static LorentzRotation transformToCMS(const LV & sum, 0362 const LV & zAxis, LV xyPlane); 0363 0364 /** 0365 * Add the elements in Cont2 to Cont1, appending them to the end if 0366 * possible. 0367 */ 0368 template <typename Cont1, typename Cont2> 0369 static void add(Cont1 & c1, const Cont2 & c2); 0370 0371 }; 0372 0373 /** Concrete class with UtilityBase as base class. */ 0374 struct Utilities: public UtilityBase {}; 0375 0376 } 0377 0378 #ifndef ThePEG_TEMPLATES_IN_CC_FILE 0379 #include "UtilityBase.tcc" 0380 #endif 0381 0382 #endif /* ThePEG_UtilityBase_H */
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|