Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:06:19

0001 // DireBasics.h is a part of the PYTHIA event generator.
0002 // Copyright (C) 2024 Stefan Prestel, Torbjorn Sjostrand.
0003 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
0004 // Please respect the MCnet Guidelines, see GUIDELINES for details.
0005 
0006 // Header file for Dire basics.
0007 
0008 #ifndef Pythia8_DireBasics_H
0009 #define Pythia8_DireBasics_H
0010 
0011 #define DIRE_BASICS_VERSION "2.002"
0012 
0013 #include "Pythia8/Event.h"
0014 #include <limits>
0015 #include <unordered_map>
0016 
0017 using std::unordered_map;
0018 
0019 namespace Pythia8 {
0020 
0021 bool checkSIJ(const Event& e, double minSIJ=0.0);
0022 void printSI(const Event& e);
0023 void printSIJ(const Event& e);
0024 
0025 typedef unsigned long ulong;
0026 
0027 //==========================================================================
0028 
0029 // Function to hash string into long integer.
0030 
0031 ulong shash(const string& str);
0032 
0033 //==========================================================================
0034 
0035 // Template to make initializing maps simpler, while not relying on C++11.
0036 // Usage: map(createmap<T,U>(a,b)(c,d)(e,f));
0037 
0038 template <typename T, typename U> class createmap {
0039 
0040 private:
0041 
0042   map<T, U> m_map;
0043 
0044 public:
0045 
0046   createmap(const T& key, const U& val) { m_map[key] = val; }
0047   createmap<T, U>& operator()(const T& key, const U& val) {
0048     m_map[key] = val;
0049     return *this;
0050   }
0051   operator map<T, U>() { return m_map; }
0052 
0053 };
0054 
0055 //==========================================================================
0056 
0057 // Template to make initializing maps simpler, while not relying on C++11.
0058 // Usage: map(createmap<T,U>(a,b)(c,d)(e,f));
0059 
0060 template <typename T, typename U> class create_unordered_map {
0061 
0062 private:
0063 
0064   unordered_map<T, U> um_map;
0065 
0066 public:
0067 
0068   create_unordered_map(const T& key, const U& val) { um_map[key] = val; }
0069   create_unordered_map<T, U>& operator()(const T& key, const U& val) {
0070     um_map[key] = val;
0071     return *this;
0072   }
0073   operator unordered_map<T, U>() { return um_map; }
0074 
0075 };
0076 
0077 //==========================================================================
0078 
0079 // Template to make initializing maps simpler, while not relying on C++11.
0080 // Usage: map(createmap<T,U>(a,b)(c,d)(e,f));
0081 
0082 template <typename T> class createvector {
0083 
0084 private:
0085 
0086   vector<T> m_vector;
0087 
0088 public:
0089 
0090   createvector(const T& val) { m_vector.push_back(val); }
0091   createvector<T>& operator()(const T& val) {
0092     m_vector.push_back(val);
0093     return *this;
0094   }
0095   operator vector<T>() { return m_vector; }
0096 
0097 };
0098 
0099 //==========================================================================
0100 
0101 // Helper function to calculate dilogarithm.
0102 
0103 double polev(double x,double* coef,int N );
0104 // Function to calculate dilogarithm.
0105 double dilog(double x);
0106 
0107 //==========================================================================
0108 
0109 // Kallen function and derived quantities.
0110 
0111 double lABC(double a, double b, double c);
0112 double bABC(double a, double b, double c);
0113 double gABC(double a, double b, double c);
0114 
0115 //==========================================================================
0116 
0117 class DireFunction {
0118 
0119 public:
0120 
0121   virtual double f(double) { return 0.; }
0122   virtual double f(double, double) { return 0.; }
0123   virtual double f(double, vector<double>) { return 0.; }
0124 
0125 };
0126 
0127 class DireRootFinder {
0128 
0129 public:
0130 
0131   DireRootFinder() {};
0132   virtual ~DireRootFinder() {};
0133 
0134   double findRootSecant1D( DireFunction* f, double xmin, double xmax,
0135     double constant, vector<double> xb = vector<double>(), int N=10 ) {
0136     vector<double> x;
0137     x.push_back(xmin);
0138     x.push_back(xmax);
0139     for ( int i=2; i < N; ++i ) {
0140       double xn = x[i-1]
0141       - ( f->f(x[i-1],xb) - constant)
0142       * ( x[i-1] - x[i-2] )
0143       / ( f->f(x[i-1],xb) - f->f(x[i-2],xb) );
0144       x.push_back(xn);
0145     }
0146     return x.back();
0147   }
0148 
0149   double findRoot1D( DireFunction* f, double xmin, double xmax,
0150     double constant, vector<double> xx = vector<double>(), int N=10,
0151     double tol = 1e-10 ) {
0152 
0153     double a(xmin), b(xmax), c(xmax), d(0.), e(0.),
0154       fa(f->f(a,xx)-constant), fb(f->f(b,xx)-constant), fc(fb),
0155       p(0.), q(0.), r(0.), s(0.),
0156       tol1(tol), xm(0.);
0157     double EPS = numeric_limits<double>::epsilon();
0158 
0159     // No root.
0160     if ( (fa>0. && fb>0.) || (fa<0. && fb<0.) ) {
0161      cout << "no root " << constant << " " << f->f(a,xx) << " " << f->f(b,xx)
0162      << endl;
0163      return numeric_limits<double>::quiet_NaN();
0164     }
0165 
0166     for ( int i=0; i < N; ++i ) {
0167 
0168       if ( (fb>0. && fc>0.) || (fb<0. && fc<0.) ) {
0169         c  = a;
0170         fc = fa;
0171         e  = d = b-a;
0172       }
0173 
0174       if ( abs(fc) < abs(fb) ) {
0175         a = b;
0176         b = c;
0177         c = a;
0178         fa = fb;
0179         fb = fc;
0180         fc = fa;
0181       }
0182 
0183       tol1 = 2.*EPS*abs(b) + 0.5*tol;
0184       xm = 0.5*(c-b);
0185 
0186       if (abs(xm) <= tol1 || fb == 0.) return b;
0187 
0188       if (abs(e) >= tol1 && abs(fa) > abs(fb) ) {
0189         s = fb/fa;
0190         if ( a == c ) {
0191           p = 2.*xm*s;
0192           q = 1.-s;
0193         } else {
0194           q = fa/fc;
0195           r = fb/fc;
0196           p = s*(2.*xm*q*(q-r) - (b-a)*(r-1.));
0197           q = (q-1.)*(r-1.)*(s-1.);
0198         }
0199         if (p>0.) q = -q;
0200         p = abs(p);
0201         double min1 = 3.*xm*q - abs(tol1*q);
0202         double min2 = abs(e*q);
0203         if (2.*p < ((min1 < min2) ? min1 : min2)) {
0204           e = d;
0205           d = p/q;
0206         } else {
0207           d = xm;
0208           e = d;
0209         }
0210 
0211       } else {
0212         d = xm;
0213         e = d;
0214       }
0215 
0216       a = b;
0217       fa = fb;
0218 
0219       if (abs(d) > tol1) { b += d; }
0220       else {
0221         b += (xm> 0.) ? tol1 : -tol1;
0222       }
0223       fb = f->f(b,xx)-constant;
0224     }
0225 
0226     // Failed. Return NaN
0227     return numeric_limits<double>::quiet_NaN();
0228 
0229   }
0230 
0231 };
0232 
0233 //==========================================================================
0234 
0235 class DireEventInfo {
0236 
0237   public:
0238 
0239   DireEventInfo() {}
0240 
0241   // Bookkeeping of soft particles.
0242   int sizeSoftPos () const { return softPosSave.size(); }
0243   int getSoftPos(unsigned int i) const {
0244     return (i > softPosSave.size()-1) ? -1 : softPosSave[i]; }
0245   bool isSoft(int iPos) {
0246     vector<int>::iterator it = find( softPosSave.begin(),
0247       softPosSave.end(), iPos);
0248     return (it != softPosSave.end());
0249   }
0250   void addSoftPos(int iPos) { if (!isSoft(iPos)) softPosSave.push_back(iPos); }
0251   void removeSoftPos(int iPos) {
0252     vector<int>::iterator it = find( softPosSave.begin(),
0253       softPosSave.end(), iPos);
0254     if (it != softPosSave.end()) softPosSave.erase(it);
0255   }
0256   void updateSoftPos(int iPosOld, int iPosNew) {
0257     if (isSoft(iPosOld)) removeSoftPos(iPosOld);
0258     if (isSoft(iPosNew)) removeSoftPos(iPosNew);
0259     addSoftPos(iPosNew);
0260   }
0261   void updateSoftPosIfMatch(int iPosOld, int iPosNew) {
0262     if (isSoft(iPosOld)) {
0263       vector<int>::iterator it
0264         = find (softPosSave.begin(), softPosSave.end(), iPosOld);
0265       *it = iPosNew;
0266     }
0267   }
0268   vector<int> softPos () const { return softPosSave; }
0269   void clearSoftPos () { softPosSave.clear(); }
0270   void listSoft() const {
0271     cout << " 'Soft' particles: ";
0272     for (int i=0; i < sizeSoftPos(); ++i) cout << setw(5) << getSoftPos(i);
0273     cout << endl;
0274   }
0275 
0276   // Bookkeeping of resonances.
0277   void removeResPos(int iPos) {
0278     vector<int>::iterator it = find (iPosRes.begin(), iPosRes.end(), iPos);
0279     if (it == iPosRes.end()) return;
0280     iPosRes.erase(it);
0281     sort (iPosRes.begin(), iPosRes.end());
0282   }
0283   void addResPos(int iPos) {
0284     vector<int>::iterator it = find (iPosRes.begin(), iPosRes.end(), iPos);
0285     if (it != iPosRes.end()) return;
0286     iPosRes.push_back(iPos);
0287     sort (iPosRes.begin(), iPosRes.end());
0288   }
0289   void updateResPos(int iPosOld, int iPosNew) {
0290     vector<int>::iterator it = find (iPosRes.begin(), iPosRes.end(), iPosOld);
0291     if (it == iPosRes.end()) iPosRes.push_back(iPosNew);
0292     else                    *it = iPosNew;
0293     sort (iPosRes.begin(), iPosRes.end());
0294   }
0295   void updateResPosIfMatch(int iPosOld, int iPosNew) {
0296     vector<int>::iterator it = find (iPosRes.begin(), iPosRes.end(), iPosOld);
0297     if (it != iPosRes.end()) {
0298       iPosRes.erase(it);
0299       iPosRes.push_back(iPosNew);
0300       sort (iPosRes.begin(), iPosRes.end());
0301     }
0302   }
0303   bool isRes(int iPos) {
0304     vector<int>::iterator it = find (iPosRes.begin(), iPosRes.end(), iPos);
0305     return (it != iPosRes.end());
0306   }
0307   int sizeResPos() const { return iPosRes.size(); }
0308   int getResPos(unsigned int i) const {
0309     return (i > iPosRes.size()-1) ? -1 : iPosRes[i]; }
0310   void clearResPos() { iPosRes.resize(0); }
0311   void listRes() const {
0312     cout << " 'Resonant' particles: ";
0313     for (int i=0; i < sizeResPos(); ++i) cout << setw(5) <<  getResPos(i);
0314     cout << endl;
0315   }
0316 
0317   // Data members.
0318   vector<int> softPosSave;
0319   vector<int> iPosRes;
0320 
0321 };
0322 
0323 
0324 //==========================================================================
0325 
0326 class DireDebugInfo {
0327 
0328   public:
0329 
0330   DireDebugInfo() = default;
0331 
0332   void clearMessages() {
0333     messageStream0.str("");
0334     messageStream1.str("");
0335     messageStream2.str("");
0336   }
0337 
0338   void printMessages( int verbosity = 0) {
0339     cout << "\n"
0340       << "*------------------------------------------------------------*\n"
0341       << "*----------------- Begin diagnostic output ------------------*\n\n";
0342     if (verbosity == 0) cout << scientific << setprecision(8)
0343     << messageStream0.str();
0344     if (verbosity == 1) cout << scientific << setprecision(8)
0345     << messageStream1.str();
0346     if (verbosity == 2) cout << scientific << setprecision(8)
0347     << messageStream2.str();
0348     cout << "\n\n"
0349       << "*----------------- End diagnostic output -------------------*\n"
0350       << "*-----------------------------------------------------------*"
0351       << endl;
0352   }
0353 
0354   void printHistograms() {}
0355 
0356   void fillHistograms(int type, int nfinal, double mec, double pT, double z) {
0357     if (false) cout << type*nfinal*mec*pT*z;}
0358 
0359   // Add debug messages to message stream.
0360   ostream & message ( int verbosity = 0) {
0361     if (verbosity == 0) return messageStream0;
0362     if (verbosity == 1) return messageStream1;
0363     if (verbosity == 2) return messageStream2;
0364     return messageStream0;
0365   }
0366 
0367   // Debug message streams.
0368   ostringstream messageStream0, messageStream1, messageStream2;
0369 
0370 };
0371 
0372 //==========================================================================
0373 
0374 class DireInfo {
0375 
0376   public:
0377 
0378   DireInfo() {}
0379 
0380   void clearAll() {
0381     direEventInfo.clearResPos();
0382     direEventInfo.clearSoftPos();
0383     direDebugInfo.clearMessages();
0384   }
0385 
0386   // Resonance info forwards.
0387   void removeResPos(int iPos)   { return direEventInfo.removeResPos(iPos); }
0388   void addResPos(int iPos)      { return direEventInfo.addResPos(iPos); }
0389   bool isRes(int iPos)          { return direEventInfo.isRes(iPos); }
0390   void clearResPos ()           { return direEventInfo.clearResPos(); }
0391   int sizeResPos() const        { return direEventInfo.sizeResPos(); }
0392   void listRes() const          { return direEventInfo.listRes(); }
0393   int getResPos(unsigned int i) const { return direEventInfo.getResPos(i); }
0394   void updateResPos(int iPosOld, int iPosNew) {
0395     return direEventInfo.updateResPos(iPosOld,iPosNew); }
0396   void updateResPosIfMatch(int iPosOld, int iPosNew) {
0397     return direEventInfo.updateResPosIfMatch(iPosOld,iPosNew); }
0398 
0399   // Debug info forwards.
0400   void printMessages( int verbosity = 0) {
0401     return direDebugInfo.printMessages(verbosity); }
0402   ostream & message ( int verbosity = 0) {
0403     return direDebugInfo.message(verbosity); }
0404   void clearMessages() { direDebugInfo.clearMessages(); }
0405 
0406   void fillHistograms(int type, int nfinal, double mec, double pT, double z) {
0407     direDebugInfo.fillHistograms(type, nfinal,  mec, pT, z); }
0408   void printHistograms() { direDebugInfo.printHistograms(); }
0409 
0410   // Soft particle info forwards.
0411   bool isSoft(int iPos)          { return direEventInfo.isSoft(iPos); }
0412   void addSoftPos(int iPos)      { return direEventInfo.addSoftPos(iPos); }
0413   void removeSoftPos(int iPos)   { return direEventInfo.removeSoftPos(iPos); }
0414   vector<int> softPos ()         { return direEventInfo.softPos(); }
0415   void clearSoftPos ()           { return direEventInfo.clearSoftPos(); }
0416   int sizeSoftPos () const       { return direEventInfo.sizeSoftPos(); }
0417   void listSoft() const          { return direEventInfo.listSoft(); }
0418   int getSoftPos(unsigned int i) const { return direEventInfo.getSoftPos(i); }
0419   void updateSoftPos(int iPosOld, int iPosNew) {
0420     return direEventInfo.updateSoftPos(iPosOld, iPosNew);
0421   }
0422   void updateSoftPosIfMatch(int iPosOld, int iPosNew) {
0423     return direEventInfo.updateSoftPosIfMatch(iPosOld, iPosNew);
0424   }
0425 
0426   DireEventInfo direEventInfo;
0427   DireDebugInfo direDebugInfo;
0428 
0429 };
0430 
0431 //==========================================================================
0432 
0433 } // end namespace Pythia8
0434 
0435 #endif // Pythia8_DireBasics_H