File indexing completed on 2025-01-18 10:06:38
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef Pythia8_LHAPDF6_H
0009 #define Pythia8_LHAPDF6_H
0010
0011 #include "Pythia8/PartonDistributions.h"
0012 #include "Pythia8/Plugins.h"
0013 #include "LHAPDF/LHAPDF.h"
0014 #include <mutex>
0015
0016 namespace Pythia8 {
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 class PdfSets {
0027
0028 public:
0029
0030
0031 PdfSets() {;}
0032 PdfSets(string setName) : info(::LHAPDF::PDFSet(setName)),
0033 pdfs(vector< ::LHAPDF::PDF* >(info.size(), 0)) {;}
0034
0035
0036 ::LHAPDF::PDF *operator[](unsigned int member) {
0037 if (!pdfs[member]) {
0038 lock_guard<mutex> lck (mtx);
0039 pdfs[member] = info.mkPDF(member);
0040 }
0041 return pdfs[member];
0042 }
0043
0044
0045 int size() {return pdfs.size();}
0046
0047
0048 ::LHAPDF::PDFSet info;
0049 vector< ::LHAPDF::PDF* > pdfs;
0050 static mutex mtx;
0051
0052 };
0053
0054 mutex PdfSets::mtx;
0055
0056
0057
0058
0059
0060 class LHAPDF6 : public PDF {
0061
0062 public:
0063
0064
0065 LHAPDF6(Pythia*, Settings* settingsPtr, Logger*) :
0066 PDF(), pdf(nullptr), extrapol(false) {
0067 if (settingsPtr == nullptr) return;
0068 sSymmetric(settingsPtr->flag("LHAPDF:sSymmetric"));
0069 cSymmetric(settingsPtr->flag("LHAPDF:cSymmetric"));
0070 bSymmetric(settingsPtr->flag("LHAPDF:bSymmetric"));
0071 }
0072
0073
0074 bool init(int idBeamIn, string setName, int member, Logger* loggerPtr)
0075 override;
0076
0077
0078 void setExtrapolate(bool extrapolIn) {extrapol = extrapolIn;}
0079
0080 private:
0081
0082
0083 PdfSets pdfs;
0084 ::LHAPDF::PDF *pdf;
0085 ::LHAPDF::Extrapolator *ext;
0086 bool extrapol;
0087
0088
0089 void xfUpdate(int id, double x, double Q2);
0090
0091
0092 bool insideBounds(double x, double Q2) {
0093 return (x > xMin && x < xMax && Q2 > q2Min && Q2 < q2Max);}
0094
0095
0096 double alphaS(double Q2) { return pdf->alphasQ2(Q2); }
0097
0098
0099 double muPDFSave, mdPDFSave, mcPDFSave, msPDFSave, mbPDFSave,
0100 xMin, xMax, q2Min, q2Max;
0101 double mQuarkPDF(int id) {
0102 switch(abs(id)){
0103 case 1: return mdPDFSave;
0104 case 2: return muPDFSave;
0105 case 3: return msPDFSave;
0106 case 4: return mcPDFSave;
0107 case 5: return mbPDFSave;
0108 }
0109 return -1.;
0110 }
0111
0112
0113 void calcPDFEnvelope(int, double, double, int);
0114 void calcPDFEnvelope(pair<int,int>, pair<double,double>, double, int);
0115 PDFEnvelope pdfEnvelope;
0116 PDFEnvelope getPDFEnvelope() {return pdfEnvelope;}
0117 static const double PDFMINVALUE;
0118
0119 int nMembersSave;
0120 int nMembers() { return nMembersSave; }
0121
0122 };
0123
0124
0125
0126
0127
0128 const double LHAPDF6::PDFMINVALUE = 1e-10;
0129
0130
0131
0132
0133
0134 bool LHAPDF6::init(int idBeamIn, string setName, int member,
0135 Logger* loggerPtr) {
0136 idBeam = idBeamIn;
0137 idBeamAbs = abs(idBeamIn);
0138 isSet = false;
0139
0140
0141
0142
0143 try {
0144 pdfs = PdfSets(setName);
0145 } catch (const std::exception &e) {
0146 loggerPtr->ERROR_MSG("unknown PDF " + setName);
0147 return false;
0148 }
0149
0150
0151 if (pdfs.size() == 0) {
0152 loggerPtr->ERROR_MSG("could not initialize PDF " + setName);
0153 return false;
0154 } else if (member >= pdfs.size()) {
0155 loggerPtr->ERROR_MSG(setName + " does not contain requested member");
0156 return false;
0157 }
0158 pdf = pdfs[member];
0159 isSet = true;
0160
0161
0162 xMax = pdf->xMax();
0163 xMin = pdf->xMin();
0164 q2Max = pdf->q2Max();
0165 q2Min = pdf->q2Min();
0166
0167
0168 muPDFSave = pdf->info().get_entry_as<double>("MUp");
0169 mdPDFSave = pdf->info().get_entry_as<double>("MDown");
0170 mcPDFSave = pdf->info().get_entry_as<double>("MCharm");
0171 msPDFSave = pdf->info().get_entry_as<double>("MStrange");
0172 mbPDFSave = pdf->info().get_entry_as<double>("MBottom");
0173 nMembersSave = pdf->info().get_entry_as<int>("NumMembers");
0174 return true;
0175
0176 }
0177
0178
0179
0180
0181
0182 void LHAPDF6::xfUpdate(int, double x, double Q2) {
0183 if (!isSet) return;
0184
0185
0186 if (x < xMin && !extrapol) x = xMin;
0187 if (x > xMax) x = xMax;
0188 if (Q2 < q2Min) Q2 = q2Min;
0189 if (Q2 > q2Max) Q2 = q2Max;
0190
0191
0192 xg = pdf->xfxQ2(21, x, Q2);
0193 xd = pdf->xfxQ2(1, x, Q2);
0194 xu = pdf->xfxQ2(2, x, Q2);
0195 xdbar = pdf->xfxQ2(-1, x, Q2);
0196 xubar = pdf->xfxQ2(-2, x, Q2);
0197 xs = pdf->xfxQ2(3, x, Q2);
0198 xc = pdf->xfxQ2(4, x, Q2);
0199 xb = pdf->xfxQ2(5, x, Q2);
0200 xsbar = sSymmetricSave ? xs : pdf->xfxQ2(-3, x, Q2);
0201 xcbar = cSymmetricSave ? xc : pdf->xfxQ2(-4, x, Q2);
0202 xbbar = bSymmetricSave ? xb : pdf->xfxQ2(-5, x, Q2);
0203 xgamma = pdf->xfxQ2(22, x, Q2);
0204
0205
0206 idSav = 9;
0207
0208 }
0209
0210
0211
0212
0213
0214 void LHAPDF6::calcPDFEnvelope(int idNow, double xNow, double Q2NowIn,
0215 int valSea) {
0216 if (!isSet) return;
0217
0218
0219 double x1 = (xNow < xMin && !extrapol) ? xMin : xNow;
0220 if (x1 > xMax) x1 = xMax;
0221 double Q2Now = (Q2NowIn < q2Min) ? q2Min : Q2NowIn;
0222 if (Q2Now > q2Max) Q2Now = q2Max;
0223
0224
0225 vector<double> xfCalc(pdfs.size());
0226 for(int iMem = 0; iMem < pdfs.size(); ++iMem) {
0227 if (valSea==0 || (idNow != 1 && idNow != 2)) {
0228 xfCalc[iMem] = pdfs[iMem]->xfxQ2(idNow, x1, Q2Now);
0229 } else if (valSea==1 && (idNow == 1 || idNow == 2 )) {
0230 xfCalc[iMem] = pdfs[iMem]->xfxQ2(idNow, x1, Q2Now) -
0231 pdfs[iMem]->xfxQ2(-idNow, x1, Q2Now);
0232 } else if (valSea==2 && (idNow == 1 || idNow == 2 )) {
0233 xfCalc[iMem] = pdfs[iMem]->xfxQ2(-idNow, x1, Q2Now);
0234 }
0235 }
0236
0237
0238 ::LHAPDF::PDFUncertainty xfErr = pdfs.info.uncertainty(xfCalc);
0239 pdfEnvelope.centralPDF = xfErr.central;
0240 pdfEnvelope.errplusPDF = xfErr.errplus;
0241 pdfEnvelope.errminusPDF = xfErr.errminus;
0242 pdfEnvelope.errsymmPDF = xfErr.errsymm;
0243 pdfEnvelope.scalePDF = xfErr.scale;
0244 }
0245
0246
0247
0248
0249
0250 void LHAPDF6::calcPDFEnvelope(pair<int,int> idNows, pair<double,double> xNows,
0251 double Q2NowIn, int valSea) {
0252 if (!isSet) return;
0253
0254
0255 double x1 = (xNows.first < xMin && !extrapol) ? xMin : xNows.first;
0256 if (x1 > xMax) x1 = xMax;
0257 double x2 = (xNows.second < xMin && !extrapol) ? xMin : xNows.second;
0258 if (x2 > xMax) x2 = xMax;
0259 double Q2Now = (Q2NowIn < q2Min) ? q2Min : Q2NowIn;
0260 if (Q2Now > q2Max) Q2Now = q2Max;
0261
0262
0263 vector<double> xfCalc(pdfs.size());
0264 pdfEnvelope.pdfMemberVars.resize(pdfs.size());
0265 for(int iMem = 0; iMem < pdfs.size(); ++iMem) {
0266 if (valSea == 0 || (idNows.first != 1 && idNows.first != 2 ) ) {
0267 xfCalc[iMem] = pdfs[iMem]->xfxQ2(idNows.first, x1, Q2Now);
0268 } else if (valSea == 1 && (idNows.first == 1 || idNows.first == 2)) {
0269 xfCalc[iMem] = pdfs[iMem]->xfxQ2(idNows.first, x1, Q2Now)
0270 - pdfs[iMem]->xfxQ2(-idNows.first, x1, Q2Now);
0271 } else if (valSea == 2 && (idNows.first == 1 || idNows.first == 2 )) {
0272 xfCalc[iMem] = pdfs[iMem]->xfxQ2(-idNows.first, x1, Q2Now);
0273 }
0274 xfCalc[iMem] = max(0.0, xfCalc[iMem]);
0275 if (valSea == 0 || (idNows.second != 1 && idNows.second != 2)) {
0276 xfCalc[iMem] /= max
0277 (PDFMINVALUE, pdfs[iMem]->xfxQ2(idNows.second, x2, Q2Now));
0278 } else if (valSea == 1 && (idNows.second == 1 || idNows.second == 2 )) {
0279 xfCalc[iMem] /= max
0280 (pdfs[iMem]->xfxQ2(idNows.second, x2, Q2Now) - pdfs[iMem]->xfxQ2
0281 (-idNows.second, x2, Q2Now), PDFMINVALUE);
0282 } else if (valSea == 2 && (idNows.second == 1 || idNows.second == 2 )) {
0283 xfCalc[iMem] /= max
0284 (pdfs[iMem]->xfxQ2(-idNows.second, x2, Q2Now), PDFMINVALUE);
0285 }
0286 pdfEnvelope.pdfMemberVars[iMem] = xfCalc[iMem];
0287 }
0288
0289
0290 ::LHAPDF::PDFUncertainty xfErr = pdfs.info.uncertainty(xfCalc);
0291 pdfEnvelope.centralPDF = xfErr.central;
0292 pdfEnvelope.errplusPDF = xfErr.errplus;
0293 pdfEnvelope.errminusPDF = xfErr.errminus;
0294 pdfEnvelope.errsymmPDF = xfErr.errsymm;
0295 pdfEnvelope.scalePDF = xfErr.scale;
0296
0297 }
0298
0299
0300
0301
0302
0303 PYTHIA8_PLUGIN_CLASS(PDF, LHAPDF6, false, false, false)
0304 PYTHIA8_PLUGIN_VERSIONS(PYTHIA_VERSION_INTEGER)
0305
0306
0307
0308 }
0309
0310 #endif