Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #ifndef METOOLS_SpinCorrelations_PolWeight_Map_H
0002 #define METOOLS_SpinCorrelations_PolWeight_Map_H
0003 
0004 #include <map>
0005 #include <set>
0006 #include <vector>
0007 #include <memory>
0008 
0009 #include "ATOOLS/Math/MyComplex.H"
0010 
0011 namespace METOOLS {
0012   class Amplitude2_Tensor;
0013 
0014   class PolWeights_Map : public std::map<std::string, Complex> {
0015     Complex m_unpolcrosssec;
0016     bool m_massive_vb, m_pol_checks;
0017     int m_trans_mode;
0018     std::map<std::string, std::string> m_custom_weights;
0019     std::string m_singlepol_channel;
0020     std::set<std::string> m_interference_weights;
0021     PolWeights_Map* p_all_weights;
0022   public:
0023     PolWeights_Map();
0024     PolWeights_Map(const METOOLS::Amplitude2_Tensor* amps, int trans_mode,
0025                    std::map<std::string, std::string> custom_weights=std::map<std::string, std::string>(),
0026                    std::string singlepol_channel="no channel", bool pol_checks=false);
0027     ~PolWeights_Map();
0028 
0029     std::set<std::string> ListofKeys() const;
0030     std::string ShortName(std::string name) const;
0031     std::set<std::string> TransverseKeys(std::set<std::string> keys, int level, bool coherent) const;
0032     std::vector<std::string> ExpandLabels(const std::vector<std::string>& transverse_labels, int level, int num_particles=0) const;
0033 
0034     void Tests(std::string prefix="");
0035 
0036     void LabelAndSeparate(const METOOLS::Amplitude2_Tensor* amps, const std::string& mode="start",
0037                           const std::string& prefix="", bool nonzero_weight= true, std::string spin_label="");
0038     void Transverse (bool coherent);
0039     void AddCustomWeights (const METOOLS::Amplitude2_Tensor* amps,
0040                            const std::vector<std::string>& finished_custom_weights);
0041     std::vector<std::string> Unpol(const METOOLS::Amplitude2_Tensor* amps,
0042                                    const std::vector<int>& unpol_particle_numbers= std::vector<int>(),
0043                                    bool non_zero_weight=true);
0044     void AddSinglePolWeights(const METOOLS::Amplitude2_Tensor* amps);
0045   };
0046 
0047   /*!
0048     \file PolWeights_Map.H
0049     \brief Declares the class METOOLS::PolWeights_Map; all methods of this class can be used for spin 1 and spin 1/2
0050            particles; class inherits from std::map
0051     */
0052   /*!
0053     \class PolWeights_Map
0054     \brief Class to extract polarization fractions from an Amplitude2_Tensor
0055 
0056       This class enables to extract polarization fractions and interference contributions from an
0057       Amplitude2_Tensor amps, assigns a reasonable label to every of those weights and save them in a C++ map;
0058       beside fractions corresponding to each possible polarization combination and a totaled interference contribution
0059       (= base weights) it can also calculate transverse polarization fractions if massive VBs are involved as
0060       intermediate particles and user-specified polarization fractions (partially unpolarized or sum of
0061       several base weights)
0062     */
0063   /*!
0064   \var Complex PolWeights_Map::m_unpolcrosssec
0065   \brief Unpolarized amplitude resulting from the sum over all entries of Amplitude2_Tensor for which the PolWeights_Map
0066          is calculated
0067   */
0068   /*!
0069   \var bool PolWeights_Map::m_massive_vb
0070   \brief Specifies whether massive VBs are included in Amplitude2_Tensor, if true, transverse weights are calculated
0071   */
0072   /*!
0073   \var int PolWeights_Map::m_trans_mode
0074   \brief Trans_mode specifies how transverse polarized cross sections should be derived from the "base" polarization
0075   combinations, 0 = incoherent sum of left and right polarization, 1 = coherent sum of left and right polarization
0076   including left-right-interference terms, 2 = cross sections/fractions for both transverse polarization definitions are
0077   calculated
0078   default: 1
0079   */
0080   /*!
0081   \var PolWeights_Map::m_pol_checks
0082   \brief Boolean specifies whether polarization consistency checks should be done (especially unpol=polsum+int and
0083    checks whether transformation works properly and is unitary)
0084   */
0085   /*!
0086   \var PolWeights_Map::m_custom_weights
0087   \brief Map containing the settings for custom weights specified by the user
0088   */
0089   /*!
0090   \var PolWeights_Map::m_singlepol_channel
0091   \brief String describes the decay channel which characterizes the only hard decaying particle which should be
0092          polarized in the desired polarized cross sections, form of the string should be the same as under Channels
0093          in Hard_Decays scoped setting e.g. 24,-11,12 for W+ decaying into a positron and a neutrino
0094   */
0095   /*!
0096   \var PolWeights_Map::m_interference_weights
0097   \brief Set contains all spin labels which describe the interference terms
0098   */
0099   /*!
0100   \var PolWeights_Map::p_all_weights
0101   \brief Pointer to a PolWeights_Map containing all fractions corresponding to all entries of the Amplitude2_Tensor and
0102    partially unpolarized fractions derived from that, this includes especially all interference terms
0103   */
0104   /*!
0105 
0106   \fn PolWeights_Map::PolWeights_Map()
0107   \brief Constructor of the class, defining an empty map
0108   */
0109   /*!
0110   \fn PolWeights_Map::PolWeights_Map(const METOOLS::Amplitude2_Tensor* amps, int trans_mode,
0111    std::map<std::string, std::string> custom_weights,
0112    std::string singlepol_channel, bool pol_checks)
0113   \brief Constructor of the class
0114 
0115    Constructor of the class generating the PolWeights_Map from given Amplitude2_Tensor, from the base weights
0116    (=normalized entries of amps) also transverse (if massive VBs are involved as intermediate particles) and custom
0117    weights (if desired) are calculated and added to the PolWeightsMap
0118   \param amps (pointer to an) Amplitude2_tensor containing all polarized matrix elements of interest
0119   \param custom_weights contains custom weights settings specified by the user, they are stored in a map with
0120                         key=Setting name in YAML-File (Weight, Weightn), value=user specified weight
0121                         (comma-separated weight names or particle numbers)
0122   \param singlepol_channel String describes the decay channel which characterizes the only hard decaying
0123                            particle which should be polarized in the desired polarized cross sections,
0124                            form of the string should be the same as under Channels in Hard_Decays scoped
0125                            setting e.g. 24,-11,12 for W+ decaying into a positron and a neutrino
0126   \param pol_checks Boolean specifies whether polarization consistency checks should be done (especially
0127                     unpol=polsum+int and checks whether transformation works properly and is unitary)
0128                     default: false
0129   */
0130   /*!
0131    \fn PolWeights_Map::ListofKeys()
0132   \brief Generate a list of all keys in a PolWeights_Map
0133   \return \c std::set<std::string> List of keys
0134   */
0135   /*!
0136   \fn   PolWeights_Map::ShortName(std::string name)
0137   \brief Reduces all doubly appearing polarization indices in spin labels to one single index
0138   \param name spin label which should be shortened
0139   \return \c std::string reduced spin label
0140   */
0141   /*!
0142   \fn PolWeights_Map::TransverseKeys(int level, bool coherent, std::set<std::string> keys)
0143   \brief Generate spin labels describing all possible polarization combinations which include at least one transverse
0144          polarized, massive VB from base spin labels where the transverse polarizations are separated in left(-)- and
0145          right-handed(+) polarization
0146   \param keys Set of basic spin labels, the method should use to determine the spin labels where left- and right-
0147               handed polarization of massive VBs are summed up; during recursive calls of the method, keys
0148               contain the intermediate spin labels which are calculated in the call of the method beforehand
0149               (can still contain left-handed- and right-handed-polarization indices for VBs at levels > current
0150               level)
0151   \param level Method goes through the spin labels by recursive calls of itself, level describes which
0152                particle in the label the current method call is working on
0153   \param coherent specifies whether spin labels should describe transverse polarized particles where the
0154                   corresponding transverse signal includes left-right interference (coherent) or not
0155                   (incoherent), they are distinguished by using capital (coherent) and small letter (incoherent)
0156                   T,t respectively                     .
0157   \return \c std::set<std::string> Set of spin labels describing all possible polarization combinations which includes at least
0158     one transverse polarized
0159   */
0160   /*!
0161   \fn PolWeights_Map::ExpandLabels(const std::vector<std::string>& transverse_labels, int level, int num_particles=0)
0162   \brief Method returns the spin labels of all polarization fractions which need to be added to receive the polarization
0163          fraction which corresponds to the passed transverse spin label;
0164          this is achieved by replacing recursively each T or t in the spin label of interest by contributing + and -
0165          polarization combinations (++, --  for incoherent definition, ++, --, +-,-+ for coherent definition, first
0166          index refers to the polarization in the matrix element, the second in its complex conjugate
0167   \param transverse_labels Vector of spin labels where at least one massive VB is transversely polarized; if the method
0168                            is called (initially), this vector should only contain one spin label; the vector object is only
0169                            chosen here for the recursive calls of the method, during which it is filled with the spin
0170                            labels to add up
0171   \param level Method goes through the spin labels by recursive calls of itself, level describes which
0172                particle in the label the current method call is working on
0173   \param num_particles Number of (intermediate) particles in the spin label; only for recursive calls,
0174                        is determined during the initial call of the method
0175   \return \c std::vector<std::string> Vector of spin labels describing all polarization fractions which need to be added to
0176     receive the polarization fraction which corresponds to the passed transverse spin label
0177   */
0178   /*!
0179   \fn PolWeights_Map::Tests(std::string prefix="")
0180   \brief Method performs some checks after the polarization weights are labeled and added to the PolWeights_Map
0181   \param prefix String specifies possible prefix in the weight name (e.g. "dc" or "Weight1")
0182   */
0183   /*!
0184   \fn PolWeights_Map::LabelAndSeparate(const METOOLS::Amplitude2_Tensor* amps, const std::string& mode="start",
0185    const std::string& prefix="", bool nonzero_weight= true, std::string spin_label="")
0186   \brief Method to label the entries of an Amplitude2_Tensor, to calculate polarization fractions from that and
0187          to separate contributions where all particles are in a definite polarization state (= polarized contributions)
0188          from terms describing interferences between different polarizations
0189 
0190   Extracts all polarized matrix elements from the provided Amplitude2_Tensor amps, normalizes them with the
0191   unpolarized result (sum over all Amplitude2_Tensor elements), provides them with a label and add them to the
0192   PolWeights_Map p_all_weights is pointing to and in case of the polarized contributions also to the PolWeights_Map
0193   this method is called on (key = label, value = polarization fraction);
0194   the idea behind this procedure is that the actual constructed PolWeights_Map only contains weights which should be
0195   printed out in the end while p_all_weights is necessary to include some interference terms into the coherent
0196   transverse signal definition;
0197   furthermore, all interference contributions are identified, summed and additionally added to the PolWeights_Map,
0198   this method is called on;
0199   general form of the spin labels:
0200     \code <particle1>.<polarization_index_in_matrix_element><polarization_index_in_complex_conjugate_matrix_element>_
0201     <particle2>.<polarization_index_in_matrix_element><polarization_index_in_complex_conjugate_matrix_element> ...
0202     \endcode
0203   order of the intermediate particles in the label is according to the order of the particles in the Amplitude2_Tensor
0204   \param amps (pointer to an) Amplitude2_Tensor containing all polarized matrix elements of interest
0205   \param mode mode describing whether the function is called the first time or whether the current
0206               fraction is already identified as interference
0207   \param prefix specifies a string which should be added at the beginning of each spin label generated
0208                 by this method
0209   \param nonzero_weight specifies whether the fractions corresponding to the generated spin labels
0210                         should be set to zero (=false), only necessary if partially unpolarized
0211                         cross sections for identical particles should be calculated where the
0212                         particles considered as polarized are characterized by a certain decay channel
0213                         (see AddSinglePolWeights method for details)
0214   \param spin_label the label for the current polarization fraction is build recursively, during
0215                     the single steps of recursion the already generated label is saved in and
0216                     propagated by the help of this variable
0217   */
0218   /*!
0219   \fn PolWeights_Map::Transverse(bool coherent)
0220   \brief Calculate transverse polarization fractions, if VB polarizations are considered, this is done
0221          by summing contributions of left- and right-handed polarization as well as left-right-interference
0222          (for coherent definition) together to one additional weight
0223   \param coherent boolean specifies which definition of the transverse polarization should be considered
0224                   (true: coherent definition including left-right interference, false: incoherent definition, no
0225                   interference included)
0226   */
0227   /*!
0228   \fn PolWeights_Map::AddCustomWeights(const METOOLS::Amplitude2_Tensor* amps,
0229                            const std::vector<std::string>& finished_custom_weights)
0230   \brief Calculate user specified additional polarization fractions if spin labels are given;
0231          polarization fractions that correspond to the user specified spin labels are totaled and added as additional
0232          weight to the PolWeights_Map
0233   \param amps (pointer to an) Amplitude2_Tensor containing all polarized matrix elements of interest
0234   \param finished_custom_weights Custom weights which are already calculated beforehand (e.g. partially
0235     unpolarized weights), necessary to test, whether each user input regarding
0236     customized polarized cross sections is valid
0237   */
0238   /*!
0239   \fn PolWeights_Map::Unpol(const METOOLS::Amplitude2_Tensor* amps,
0240                             const std::vector<int>& unpol_particle_numbers= std::vector<int>(),
0241                             bool non_zero_weight=true)
0242   \brief Calculate polarization fractions where one or several intermediate particles are considered as unpolarized
0243   \param amps (pointer to an) Amplitude2_Tensor containing all polarized matrix elements of interest
0244   \param unpol_particle_numbers vector containing the number of those particles which should be considered as
0245                                        unpolarized; numbers according to particle numbering in Sherpa;
0246                                        unpol_particle_numbers being not empty is only necessary, if m_custom_weights
0247                                        does not contain the particle numbers of those particles which should be
0248                                        considered as unpolarized, e.g. if partially unpolarized weights should be
0249                                        calculated for processes with identical particles involved and particles
0250                                        decaying via a certain decay channel should be considered as polarized
0251   \return std::vector<std::string> Vector of user inputs specifying which custom weights of the desired ones are already
0252     calculated by this method
0253   */
0254   /*!
0255   \fn PolWeights_Map::AddSinglePolWeights(METOOLS::Amplitude2_Tensor* amps)
0256   \brief Calculate single polarization fractions for processes with identical intermediate particles like in
0257    same sign VB pair production, single polarized particle is specified by its decay channel
0258    private version, no yet included in manual
0259   \param amps (pointer to an) Amplitude2_Tensor containing all polarized matrix elements of interest
0260   */
0261 }
0262 
0263 #endif