Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-10-15 08:24:45

0001 // PHHerwig7Core.h -- drive Herwig 7 in-process through its public API.
0002 //
0003 // No Fun4All and no HepMC dependency here, so the same code is exercised by
0004 // the PHHerwig7 SubsysReco on RCF (HepMC2) and by the standalone smoke test
0005 // on a machine with only Herwig (hwgen_test.cc, HepMC3).
0006 //
0007 // What Herwig's own `Herwig run file.run -N n -s seed` does, and what this
0008 // reproduces, is (Herwig-7.3.0/API/HerwigAPI.cc, HerwigGenericRun):
0009 //   PersistentIStream(runfile) >> eg;   eg->setSeed(seed);   eg->initialize();
0010 //   loop: eg->shoot();                  eg->finalize();
0011 // prepareRun() covers everything up to and including initialize().
0012 #ifndef PHHERWIG7CORE_H
0013 #define PHHERWIG7CORE_H
0014 
0015 #include <Herwig/API/HerwigAPI.h>
0016 #include <Herwig/API/HerwigUI.h>
0017 
0018 #include <ThePEG/Config/Unitsystem.h>
0019 #include <ThePEG/EventRecord/Event.h>
0020 #include <ThePEG/Interface/InterfaceBase.h>
0021 #include <ThePEG/Repository/BaseRepository.h>
0022 #include <ThePEG/Repository/EventGenerator.h>
0023 #include <ThePEG/Repository/Repository.h>
0024 
0025 #include <cstdlib>
0026 #include <iostream>
0027 #include <stdexcept>
0028 #include <string>
0029 #include <vector>
0030 
0031 // The command-line options Herwig's CLI would carry, as a plain struct.
0032 class PHHerwigUI : public Herwig::HerwigUI
0033 {
0034  public:
0035   PHHerwigUI() = default;
0036   ~PHHerwigUI() override = default;
0037 
0038   Herwig::RunMode::Mode runMode() const override { return Herwig::RunMode::RUN; }
0039   std::string repository() const override { return m_Repository; }
0040   std::string inputfile() const override { return m_RunFile; }
0041   std::string setupfile() const override { return m_SetupFile; }
0042   bool resume() const override { return false; }
0043   bool tics() const override { return false; }
0044   std::string tag() const override { return m_Tag; }
0045   std::string integrationList() const override { return std::string(); }
0046   const std::vector<std::string> &prependReadDirectories() const override { return m_Prepend; }
0047   const std::vector<std::string> &appendReadDirectories() const override { return m_Append; }
0048   long N() const override { return m_N; }
0049   int seed() const override { return m_Seed; }
0050   int jobs() const override { return 1; }
0051   unsigned int jobSize() const override { return 0; }
0052   unsigned int maxJobs() const override { return 0; }
0053   void quitWithHelp() const override { throw std::runtime_error("PHHerwigUI: Herwig asked to quit (see messages above)"); }
0054   void quit() const override { throw std::runtime_error("PHHerwigUI: Herwig asked to quit (see messages above)"); }
0055   std::ostream &outStream() const override { return std::cout; }
0056   std::ostream &errStream() const override { return std::cerr; }
0057   std::istream &inStream() const override { return std::cin; }
0058 
0059   std::string m_Repository = "HerwigDefaults.rpo";
0060   std::string m_RunFile;
0061   std::string m_SetupFile;
0062   std::string m_Tag;
0063   std::vector<std::string> m_Prepend;
0064   std::vector<std::string> m_Append;
0065   long m_N = 0;
0066   int m_Seed = 0;
0067 };
0068 
0069 class PHHerwig7Core
0070 {
0071  public:
0072   PHHerwig7Core() = default;
0073   ~PHHerwig7Core()
0074   {
0075     if (m_Generator && !m_Finished)
0076     {
0077       finish();
0078     }
0079   }
0080   PHHerwig7Core(const PHHerwig7Core &) = delete;
0081   PHHerwig7Core &operator=(const PHHerwig7Core &) = delete;
0082 
0083   PHHerwigUI &ui() { return m_UI; }
0084 
0085   // Load the .run file, seed, initialize.  Throws std::runtime_error on failure.
0086   void init()
0087   {
0088     if (m_UI.m_RunFile.empty())
0089     {
0090       throw std::runtime_error("PHHerwig7Core::init - no run file set");
0091     }
0092     ThePEG::Repository::exitOnError() = 1;  // as the Herwig CLI does
0093     m_Generator = Herwig::API::prepareRun(m_UI);
0094     if (!m_Generator)
0095     {
0096       throw std::runtime_error("PHHerwig7Core::init - prepareRun returned no EventGenerator");
0097     }
0098     // The .run file carries the card's NumberOfEvents and shoot() returns
0099     // nothing once that many have been generated.  Fun4All owns the event
0100     // count here, so lift the limit (Herwig's own -N does the same).
0101     // N(long) is protected; go through the interface as a setup file would.
0102     const ThePEG::InterfaceBase *ifc = ThePEG::BaseRepository::FindInterface(m_Generator, "NumberOfEvents");
0103     if (ifc)
0104     {
0105       ifc->exec(*m_Generator, "set", std::to_string(m_MaxEvents));
0106     }
0107     else
0108     {
0109       std::cerr << "PHHerwig7Core::init - cannot find NumberOfEvents interface; generator will stop after "
0110                 << m_Generator->N() << " events" << std::endl;
0111     }
0112     m_Finished = false;
0113   }
0114 
0115   // generator-side cap on events shot; default -1 = unlimited (Fun4All decides)
0116   void set_max_events(long n) { m_MaxEvents = n; }
0117 
0118   // One event.  Returns a null pointer only if Herwig gives up on the event.
0119   ThePEG::EventPtr next()
0120   {
0121     ThePEG::EventPtr ev = m_Generator->shoot();
0122     if (ev)
0123     {
0124       ++m_NGenerated;
0125       m_SumWeights += ev->weight();
0126     }
0127     return ev;
0128   }
0129 
0130   void finish()
0131   {
0132     if (m_Generator && !m_Finished)
0133     {
0134       m_Generator->finalize();
0135       m_Finished = true;
0136     }
0137   }
0138 
0139   ThePEG::EventGenerator *generator() { return m_Generator ? &(*m_Generator) : nullptr; }
0140 
0141   // integrated cross section of the running sampler, in pb
0142   double xsec_pb() const
0143   {
0144     if (!m_Generator) return 0.0;
0145     const double x = m_Generator->integratedXSec() / ThePEG::Units::picobarn;
0146     return x;
0147   }
0148   double xsec_err_pb() const
0149   {
0150     if (!m_Generator) return 0.0;
0151     const double x = m_Generator->integratedXSecErr() / ThePEG::Units::picobarn;
0152     return x;
0153   }
0154   long n_generated() const { return m_NGenerated; }
0155   double sum_weights() const { return m_SumWeights; }
0156 
0157  private:
0158   PHHerwigUI m_UI;
0159   ThePEG::EGPtr m_Generator;
0160   bool m_Finished = true;
0161   long m_NGenerated = 0;
0162   double m_SumWeights = 0.0;
0163   long m_MaxEvents = -1;  // ThePEG: negative = unlimited
0164 };
0165 
0166 #endif