// LHAPDF6.h is a part of the PYTHIA event generator. // Copyright (C) 2017 Torbjorn Sjostrand. // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details. // Please respect the MCnet Guidelines, see GUIDELINES for details. // This file contains the LHAPDF6 PDF plugin class. #ifndef Pythia8_LHAPDF6_H #define Pythia8_LHAPDF6_H #include "Pythia8/PartonDistributions.h" #include "LHAPDF/LHAPDF.h" namespace Pythia8 { //========================================================================== // Global tracking of opened PDF sets. //-------------------------------------------------------------------------- namespace LHAPDF6Interface { // Define opened PDF sets global variable. map< int, pair< ::LHAPDF::PDF*, int > > initializedSets; } //========================================================================== // Provide interface to the LHAPDF6 library of parton densities. class LHAPDF6 : public PDF { public: // Constructor. LHAPDF6(int idBeamIn, string setName, int member, int, Info* infoPtr) : PDF(idBeamIn), id (-1), pdf(0), extrapol(false) {init(setName, member, infoPtr);} // Destructor. ~LHAPDF6(); // Allow extrapolation beyond boundaries (not implemented). void setExtrapolate(bool extrapolIn) {extrapol = extrapolIn;} private: // The LHAPDF objects. int id; ::LHAPDF::PDF *pdf; ::LHAPDF::Extrapolator *ext; bool extrapol; // Initialization of PDF set. void init(string setName, int member, Info* infoPtr); // Update parton densities. void xfUpdate(int id, double x, double Q2); // Check whether x and Q2 values fall inside the fit bounds. bool insideBounds(double x, double Q2) { return ( x > pdf->xMin() && x < pdf->xMax() && Q2 > pdf->q2Min() && Q2 < pdf->q2Max() ); } // Return the running alpha_s shipped with the LHAPDF set. double alphaS(double Q2) { return pdf->alphasQ2(Q2); } // Return quark masses used in the PDF fit. double muPDFSave, mdPDFSave, mcPDFSave, msPDFSave, mbPDFSave; double mQuarkPDF(int id) { if (abs(id) == 1) return mdPDFSave; if (abs(id) == 2) return muPDFSave; if (abs(id) == 3) return msPDFSave; if (abs(id) == 4) return mcPDFSave; if (abs(id) == 5) return mbPDFSave; return -1.; } }; //-------------------------------------------------------------------------- // Destructor. LHAPDF6::~LHAPDF6() { map< int, pair< ::LHAPDF::PDF*, int > >::iterator set = LHAPDF6Interface::initializedSets.find(id); if (set == LHAPDF6Interface::initializedSets.end()) return; set->second.second--; if (set->second.second == 0) { delete set->second.first; LHAPDF6Interface::initializedSets.erase(set); } } //-------------------------------------------------------------------------- // Initialize a parton density function from LHAPDF6. void LHAPDF6::init(string setName, int member, Info *info) { isSet = false; // Initialize the set if not initialized. id = ::LHAPDF::lookupLHAPDFID(setName, member); if (id < 0) { info->errorMsg("Error in LHAPDF6::init: unknown PDF " + setName); return; } else if (LHAPDF6Interface::initializedSets.find(id) == LHAPDF6Interface::initializedSets.end()) { pdf = ::LHAPDF::mkPDF(id); if (!pdf) { info->errorMsg("Error in LHAPDF6::init: could not initialize PDF " + setName); return; } else LHAPDF6Interface::initializedSets[id] = pair< ::LHAPDF::PDF*, int>(pdf, 0); } else { pair< ::LHAPDF::PDF*, int > &set = LHAPDF6Interface::initializedSets[id]; pdf = set.first; set.second++; } isSet = true; // Store quark masses used in PDF fit. muPDFSave = pdf->info().get_entry_as("MUp"); mdPDFSave = pdf->info().get_entry_as("MDown"); mcPDFSave = pdf->info().get_entry_as("MCharm"); msPDFSave = pdf->info().get_entry_as("MStrange"); mbPDFSave = pdf->info().get_entry_as("MBottom"); } //-------------------------------------------------------------------------- // Give the parton distribution function set from LHAPDF6. void LHAPDF6::xfUpdate(int, double x, double Q2) { // Freeze at boundary value if PDF is evaluated outside the fit region. if (x < pdf->xMin() ) x = pdf->xMin(); if (x > pdf->xMax() ) x = pdf->xMax(); if (Q2 < pdf->q2Min() ) Q2 = pdf->q2Min(); if (Q2 > pdf->q2Max() ) Q2 = pdf->q2Max(); // Update values. xg = pdf->xfxQ2(21, x, Q2); xu = pdf->xfxQ2(2, x, Q2); xd = pdf->xfxQ2(1, x, Q2); xs = pdf->xfxQ2(3, x, Q2); xubar = pdf->xfxQ2(-2, x, Q2); xdbar = pdf->xfxQ2(-1, x, Q2); xsbar = pdf->xfxQ2(-3, x, Q2); xc = pdf->xfxQ2(4, x, Q2); xb = pdf->xfxQ2(5, x, Q2); xgamma = pdf->xfxQ2(22, x, Q2); // Subdivision of valence and sea. xuVal = xu - xubar; xuSea = xubar; xdVal = xd - xdbar; xdSea = xdbar; // idSav = 9 to indicate that all flavours reset. idSav = 9; } //-------------------------------------------------------------------------- // Define external handles to the plugin for dynamic loading. extern "C" LHAPDF6* newLHAPDF(int idBeamIn, string setName, int member, Info* infoPtr) { return new LHAPDF6(idBeamIn, setName, member, 1, infoPtr); } extern "C" void deleteLHAPDF(LHAPDF6* pdf) { delete pdf; } //========================================================================== } // end namespace Pythia8 #endif // end Pythia8_LHAPDF6_H