Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:29:38

0001 
0002 #include "GeneratorInterface/Core/interface/BaseHadronizer.h"
0003 #include "FWCore/ParameterSet/interface/Registry.h"
0004 
0005 #include <random>
0006 #include <sys/wait.h>
0007 
0008 namespace gen {
0009 
0010   const std::vector<std::string> BaseHadronizer::theSharedResources;
0011 
0012   BaseHadronizer::BaseHadronizer(edm::ParameterSet const& ps) : randomIndex_(-1), gridpackPaths_(1) {
0013     if (ps.exists("RandomizedParameters")) {
0014       std::vector<edm::ParameterSet> randomizedParameters =
0015           ps.getParameter<std::vector<edm::ParameterSet> >("RandomizedParameters");
0016       randomInitWeights_.resize(randomizedParameters.size());
0017       randomInitConfigDescriptions_.resize(randomizedParameters.size());
0018       gridpackPaths_.resize(randomizedParameters.size());
0019       for (unsigned int irand = 0; irand < randomizedParameters.size(); ++irand) {
0020         randomInitWeights_[irand] = randomizedParameters[irand].getParameter<double>("ConfigWeight");
0021         if (randomizedParameters[irand].exists("ConfigDescription")) {
0022           randomInitConfigDescriptions_[irand] =
0023               randomizedParameters[irand].getParameter<std::string>("ConfigDescription");
0024         }
0025         if (randomizedParameters[irand].exists("GridpackPath")) {
0026           gridpackPaths_[irand] = randomizedParameters[irand].getParameter<std::string>("GridpackPath");
0027         }
0028       }
0029     } else {
0030       if (ps.exists("GridpackPath")) {
0031         gridpackPaths_[0] = ps.getParameter<std::string>("GridpackPath");
0032       }
0033     }
0034 
0035     runInfo().setFilterEfficiency(ps.getUntrackedParameter<double>("filterEfficiency", -1.));
0036     runInfo().setExternalXSecLO(GenRunInfoProduct::XSec(ps.getUntrackedParameter<double>("crossSection", -1.)));
0037     runInfo().setExternalXSecNLO(GenRunInfoProduct::XSec(ps.getUntrackedParameter<double>("crossSectionNLO", -1.)));
0038   }
0039 
0040   std::unique_ptr<GenLumiInfoHeader> BaseHadronizer::getGenLumiInfoHeader() const {
0041     auto genLumiInfoHeader = std::make_unique<GenLumiInfoHeader>();
0042 
0043     //fill information on randomized configs for parameter scans
0044     genLumiInfoHeader->setRandomConfigIndex(randomIndex_);
0045     if (randomIndex_ >= 0) {
0046       genLumiInfoHeader->setConfigDescription(randomInitConfigDescription());
0047     }
0048 
0049     return genLumiInfoHeader;
0050   }
0051 
0052   void BaseHadronizer::randomizeIndex(edm::LuminosityBlock const& lumi, CLHEP::HepRandomEngine* rengine) {
0053     if (!randomInitWeights_.empty()) {
0054       //randomly select from a list of provided configuration sets (for parameter scans)
0055 
0056       //seeds std 32-bit mersene twister with HepRandomEngine state plus run and lumi section numbers
0057       //(random engine state will be the same for every lumi section in a job)
0058       std::vector<long unsigned int> seeds = rengine->put();
0059       seeds.push_back(lumi.id().run());
0060       seeds.push_back(lumi.id().luminosityBlock());
0061       std::seed_seq seedseq(seeds.begin(), seeds.end());
0062       std::mt19937 randgen(seedseq);
0063       std::discrete_distribution<int> randdist(randomInitWeights_.begin(), randomInitWeights_.end());
0064 
0065       randomIndex_ = randdist(randgen);
0066     }
0067   }
0068 
0069   void BaseHadronizer::generateLHE(edm::LuminosityBlock const& lumi,
0070                                    CLHEP::HepRandomEngine* rengine,
0071                                    unsigned int ncpu) {
0072     if (gridpackPath().empty()) {
0073       return;
0074     }
0075 
0076     //get random seed from HepRandomEngine state plus run and lumi section numbers
0077     //(random engine state will be the same for every lumi section in a job)
0078     std::vector<long unsigned int> seeds = rengine->put();
0079     seeds.push_back(lumi.id().run());
0080     seeds.push_back(lumi.id().luminosityBlock());
0081     std::seed_seq seedseq(seeds.begin(), seeds.end());
0082     std::array<unsigned int, 1> lheseed;
0083     seedseq.generate(lheseed.begin(), lheseed.end());
0084 
0085     constexpr unsigned int maxseed = 30081 * 30081;  //madgraph cannot handle seeds larger than this
0086     unsigned int seedval = lheseed[0] % (maxseed + 1);
0087 
0088     unsigned int nevents = edm::pset::Registry::instance()
0089                                ->getMapped(lumi.processHistory().rbegin()->parameterSetID())
0090                                ->getParameter<edm::ParameterSet>("@main_input")
0091                                .getUntrackedParameter<unsigned int>("numberEventsInLuminosityBlock");
0092 
0093     std::ostringstream nevStream;
0094     nevStream << nevents;
0095 
0096     std::ostringstream randomStream;
0097     randomStream << seedval;
0098 
0099     edm::FileInPath script("GeneratorInterface/LHEInterface/data/run_generic_tarball_cvmfs.sh");
0100     const char* outfilename = "cmsgrid_final.lhe";
0101 
0102     std::array<std::string, 5> argStrs;
0103     argStrs[0] = script.fullPath();
0104     argStrs[1] = gridpackPath();
0105     argStrs[2] = nevStream.str();
0106     argStrs[3] = randomStream.str();
0107     argStrs[4] = std::to_string(ncpu);
0108     std::array<char*, 6> args{
0109         {&argStrs[0][0], &argStrs[1][0], &argStrs[2][0], &argStrs[3][0], &argStrs[4][0], nullptr}};
0110 
0111     pid_t pid = fork();
0112 
0113     if (pid == -1) {
0114       // error, failed to fork()
0115       throw cms::Exception("BaseHadronizer::generateLHE") << "Unable to fork a child";
0116     } else if (pid == 0) {
0117       //child
0118       execvp(args[0], std::begin(args));
0119       _exit(1);  // exec never returns
0120     } else {
0121       //parent
0122       int status;
0123       waitpid(pid, &status, 0);
0124       if (status) {
0125         throw cms::Exception("BaseHadronizer::generateLHE") << "Failed to execute script";
0126       }
0127     }
0128     FILE* lhef = std::fopen(outfilename, "r");
0129     if (!lhef) {
0130       throw cms::Exception("BaseHadronizer::generateLHE") << "Output file " << outfilename << " not found.";
0131     }
0132     std::fclose(lhef);
0133 
0134     lheFile_ = outfilename;
0135   }
0136 
0137   void BaseHadronizer::cleanLHE() {
0138     if (lheFile_.empty()) {
0139       return;
0140     }
0141 
0142     std::remove(lheFile_.c_str());
0143   }
0144 
0145 }  // namespace gen