Back to home page

EIC code displayed by LXR

 
 

    


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 */