main136
Back to index.
// main136.cc is a part of the PYTHIA event generator.
// Copyright (C) 2025 Torbjorn Sjostrand.
// PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
// Please respect the MCnet Guidelines, see GUIDELINES for details.
// Authors:
//            Christian T. Preuss
// Keywords:
//            HDF5 file
//            LHEH5
//            Hepmc
// This program (main136.cc) illustrates how a HDF5 event file can be
// used by Pythia8. See main134.cc for how to use LHE files instead.
// Example usage is:
//     ./main136 -c main136.cmnd -i ttbar.hdf5 -o main136.hepmc
#include "Pythia8/Pythia.h"
// To use v2 of LHAHDF5, include "Pythia8Plugins/LHAHDF5v2.h" instead.
//#include "Pythia8Plugins/LHAHDF5v2.h"
#include "Pythia8Plugins/LHAHDF5.h"
#include "Pythia8Plugins/InputParser.h"
#ifndef HEPMC2
#include "Pythia8Plugins/HepMC3.h"
#else
#include "Pythia8Plugins/HepMC2.h"
#endif
using namespace Pythia8;
//==========================================================================
// Example main programm to illustrate simple HDF5 usage.
int main(int argc, char* argv[]) {
  // Set up command line options.
  InputParser ip("Illustrates how a HDF5 event file can be used by Pythia8.",
    {"./main136 -c main136.cmnd -i ttbar.hdf5 -o main136.hepmc"});
  ip.require("c", "Use this user-written command file.", {"-cmnd"});
  ip.require("o", "Specify HepMC output filename.", {"-out"});
  ip.require("i", "Specify HDF5 input filename.", {"-in"});
  // Initialize the parser and exit if necessary.
  InputParser::Status status = ip.init(argc, argv);
  if (status != InputParser::Valid) return status;
  // Check whether input file exists.
  string cmndFile = ip.get<string>("c");
  ifstream isCmnd(cmndFile);
  if (!isCmnd) {
    cerr << " File " << cmndFile << " was not found. \n"
         << " Program stopped! " << endl;
    return EXIT_FAILURE;
  }
  // Check whether event file exists.
  string hdf5File = ip.get<string>("i");
  ifstream isH5(hdf5File);
  if (!isH5) {
    cerr << " File " << hdf5File << " was not found. \n"
         << " Program stopped! " << endl;
    return EXIT_FAILURE;
  }
  // Optionally: skip events.
  size_t eventOffset = (argc > 4) ? atoi(argv[4]) : 0;
  // PYTHIA.
  Pythia pythia;
  // Settings.
  pythia.readFile(cmndFile);
  pythia.settings.mode("Beams:frameType", 5);
  // Shorthands.
  int nEvents  = pythia.settings.mode("Main:numberOfEvents");
  int nAbort   = pythia.mode("Main:timesAllowErrors");
  // HDF5.
  HighFive::File file(hdf5File, HighFive::File::ReadOnly);
  // Create an LHAup object that can access relevant information in pythia.
  size_t readSize    = size_t(nEvents);
  string version     = pythia.settings.word("LHAHDF5:version");
  shared_ptr<LHAupH5> lhaUpPtr =
    make_shared<LHAupH5>(&file, eventOffset, readSize, version);
  // When using v2 of LHAHDF5, then use the following.
  // shared_ptr<LHAupH5v2> lhaUpPtr =
  //   make_shared<LHAupH5v2>(&file, eventOffset, readSize, true);
  // HepMC.
  string hepMCFile = ip.get<string>("o");
  Pythia8::Pythia8ToHepMC toHepMC(hepMCFile);
  toHepMC.set_print_inconsistency(false);
  // Hand Pythia the external reader.
  pythia.setLHAupPtr(lhaUpPtr);
  // Initialise.
  if (!pythia.init()) {
    cout << " Failed to initialise Pythia. Program stopped." << endl;
    return EXIT_FAILURE;
  }
  // Abort for too many errors.
  int  iAbort  = 0;
  bool doAbort = false;
  // Cross section and error.
  cout << "Start generating events.\n";
  double sigmaSample(0.), errorSample(0.);
  // Get the inclusive x-section by summing over all process x-sections.
  double xs = 0.;
  for (int i=0; i < pythia.info.nProcessesLHEF(); ++i)
    xs += pythia.info.sigmaLHEF(i);
  // Loop over events.
  while(pythia.info.nSelected() < nEvents) {
    // Generate next event.
    if( !pythia.next() ) {
      ++iAbort;
      if ( pythia.info.atEndOfFile() ) break;
      else if (iAbort > nAbort) {
        cout <<  " Aborting event generation after "
             << iAbort << " failed events." << endl;
        break;
      } else continue;
    }
    // Get event weight(s).
    double evtweight = pythia.info.weight();
    // Do not print zero-weight events.
    if ( evtweight == 0. ) continue;
    // Fill HepMC event.
    toHepMC.writeNextEvent(pythia);
    sigmaSample += evtweight;
    errorSample += pow2(evtweight);
  }
  // print cross section, errors
  pythia.stat();
  // Finalise cross section.
  double norm = 1./double(1.e9*lhaUpPtr->nTrials());
  if (abs(pythia.info.lhaStrategy()) == 3) norm *= xs;
  sigmaSample *= norm;
  errorSample = sqrt(errorSample)*norm;
  cout << " sigma = (" << scientific << setprecision(8)
       << sigmaSample << "  +-  " << errorSample << ") mb\n";
  // Done
  return 0;
}