// -*- C++ -*- // // This file is part of LHAPDF // Copyright (C) 2012-2021 The LHAPDF collaboration (see AUTHORS for details) // #include "LHAPDF/Paths.h" #include "LHAPDF/Info.h" #include "LHAPDF/Config.h" #include <dirent.h> #ifdef HAVE_MPI #include <mpi.h> #endif namespace LHAPDF { std::vector<std::string> paths() { // Use LHAPDF_DATA_PATH for all path storage char* pathsvar = getenv("LHAPDF_DATA_PATH"); // But fall back to looking in LHAPATH if the preferred var is not defined if (pathsvar == nullptr) pathsvar = getenv("LHAPATH"); const string spathsvar = (pathsvar != 0) ? pathsvar : ""; // Split the paths variable as usual vector<string> rtn = split(spathsvar, ":"); // Look in the install prefix after other paths are exhausted, if not blocked by a trailing :: if (spathsvar.length() < 2 || spathsvar.substr(spathsvar.length()-2) != "::") { volatile auto default_prefix = LHAPDF_DATA_PREFIX; //< needed to avoid overoptimisation bug const string datadir = string(default_prefix) / "LHAPDF"; rtn.push_back(datadir); } return rtn; } void setPaths(const std::string& pathstr) { setenv("LHAPDF_DATA_PATH", pathstr.c_str(), 1); } string findFile(const string& target) { if (target.empty()) return ""; for (const string& base : paths()) { const string p = (startswith(target, "/") || startswith(target, ".")) ? target : base / target; // if (verbosity() > 2) cout << "Trying file: " << p << endl; if (file_exists(p)) { // if (verbosity() > 1) cout << "Found file: " << p << endl; return p; } } return ""; } const std::vector<std::string>& availablePDFSets() { // Cached path list static vector<string> rtn; // Return cached list if valid if (!rtn.empty()) return rtn; // Otherwise this is the first time: populate the list #ifdef HAVE_MPI if (MPI::COMM_WORLD.Get_rank()==0) #endif for (const string& p : paths()) { if (!dir_exists(p,1)) continue; DIR* dir; struct dirent* ent; if ((dir = opendir(p.c_str())) != NULL) { while ((ent = readdir(dir)) != NULL) { const string d = ent->d_name; const string infopath = p / d / d + ".info"; if (file_exists(infopath,1)) { if (!contains(rtn, d)) { // cout << "@" << d << "@" << endl; rtn.push_back(d); //< add if a set with this name isn't already known } } } closedir(dir); } sort(rtn.begin(), rtn.end()); } #ifdef HAVE_MPI if (MPI::COMM_WORLD.Get_rank()==0) { std::string allrtn; for (size_t i=0;i<rtn.size();++i) allrtn+="*"+rtn[i]; int nchar(allrtn.length()); MPI::COMM_WORLD.Bcast(&nchar,1,MPI_INT,0); MPI::COMM_WORLD.Bcast(&allrtn[0],nchar,MPI_CHAR,0); } else { int nchar; MPI::COMM_WORLD.Bcast(&nchar,1,MPI_INT,0); std::string allrtn(nchar,' '); MPI::COMM_WORLD.Bcast(&allrtn[0],nchar,MPI_CHAR,0); size_t bpos(allrtn.find('*')); while (bpos<allrtn.length()) { size_t epos(std::min(allrtn.length(),allrtn.find('*',bpos+1))); rtn.push_back(allrtn.substr(bpos+1,epos-bpos-1)); bpos=epos; } } #endif return rtn; } }