Skip to content

Commit

Permalink
Interface to the CepGen event generator
Browse files Browse the repository at this point in the history
Along with the "generator filter" implementation linking everything together, this contains
generator fragments for a LPAIR and a PPtoFF single-dissociative generation.
The PPtoFF fragment also demonstrates the capability to use Pythia 6 for the fragmentation
of the dissociative beam remnants.

Requires CepGen v1.2.0 at least.
  • Loading branch information
forthommel committed Feb 29, 2024
1 parent b4572d4 commit 69e7cae
Show file tree
Hide file tree
Showing 11 changed files with 305 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import FWCore.ParameterSet.Config as cms

from GeneratorInterface.CepGenInterface.cepgenDefaultParameters_cff import *

generator = cms.EDFilter("CepGenGeneratorFilter",
process = cms.PSet(
name = cms.string('lpair'),
kinematics = cms.PSet(
mode = cms.uint32(2), # 1 = elastic, 2-3 = SD, 4 = DD
structureFunctions = cms.PSet(
name = cms.int32(301) # see https://cepgen.hepforge.org/raw-modules
),
cmEnergy = cms.double(13000.0),
eta = cms.vdouble(-2.5, 2.5),
pt = cms.vdouble(25., 9999.)
),
processParameters = cms.PSet(
pair = cms.uint32(13)
)
),
modifierModules = cepgenPythia6BeamFragmenter,
outputModules = cepgenOutputModules,
maxEventsToPrint = cms.untracked.int32(0),
verbosity = cms.untracked.int32(0)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import FWCore.ParameterSet.Config as cms

from GeneratorInterface.CepGenInterface.cepgenDefaultParameters_cff import *

generator = cms.EDFilter("CepGenGeneratorFilter",
process = cms.PSet(
name = cms.string('pptoff'),
kinematics = cms.PSet(
mode = cms.uint32(2), # 1 = elastic, 2-3 = SD, 4 = DD
structureFunctions = cms.PSet(
name = cms.int32(301) # see https://cepgen.hepforge.org/raw-modules
),
cmEnergy = cms.double(13000.0),
qt = cms.vdouble(0., 50.),
rapidity = cms.vdouble(-6., 6.),
eta = cms.vdouble(-2.5, 2.5),
pt = cms.vdouble(25., 9999.),
ptdiff = cms.vdouble(0., 500.)
),
processParameters = cms.PSet(
ktFactorised = cms.bool(True),
pair = cms.uint32(13)
)
),
outputModules = cepgenOutputModules,
maxEventsToPrint = cms.untracked.int32(0),
verbosity = cms.untracked.int32(0)
)
10 changes: 10 additions & 0 deletions GeneratorInterface/CepGenInterface/BuildFile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<use name="CepGen"/>
<lib name="CepGenHepMC2"/>
<use name="FWCore/Framework"/>
<use name="GeneratorInterface/Core"/>
<use name="clhep"/>
<use name="hepmc"/>
<flags CXXFLAGS="-Wno-error=missing-braces -Wno-missing-braces -Wno-non-virtual-dtor"/>
<export>
<lib name="1"/>
</export>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// CepGen-CMSSW interfacing module
// 2022-2024, Laurent Forthomme

#ifndef GeneratorInterface_CepGenInterface_CepGenEventGenerator_h
#define GeneratorInterface_CepGenInterface_CepGenEventGenerator_h

#include "FWCore/Framework/interface/ConsumesCollector.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "GeneratorInterface/Core/interface/BaseHadronizer.h"

#include <CepGen/Generator.h>

namespace gen {
class CepGenEventGenerator : public BaseHadronizer {
public:
explicit CepGenEventGenerator(const edm::ParameterSet&, edm::ConsumesCollector&&);
virtual ~CepGenEventGenerator();

bool readSettings(int) { return true; }
bool declareStableParticles(const std::vector<int>&) { return true; }
bool declareSpecialSettings(const std::vector<std::string>&) { return true; }

bool initializeForInternalPartons();
bool generatePartonsAndHadronize();
bool decay() { return true; } // NOT used - let's call it "design imperfection"
bool residualDecay() { return true; }

void finalizeEvent() {}
void statistics() {}

const char* classname() const { return "CepGenEventGenerator"; }
const std::vector<std::string>& doSharedResources() const override { return shared_resources_; }

private:
cepgen::Generator* gen_{nullptr};
const cepgen::ParametersList proc_params_;
std::vector<std::pair<std::string, cepgen::ParametersList> > modif_modules_, output_modules_;
const std::vector<std::string> shared_resources_;
HepMC::GenCrossSection xsec_;
};
} // namespace gen

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// CepGen-CMSSW interfacing module
// 2022-2024, Laurent Forthomme

#ifndef GeneratorInterface_CepGenInterface_CepGenGeneratorFilter_h
#define GeneratorInterface_CepGenInterface_CepGenGeneratorFilter_h

#include "GeneratorInterface/Core/interface/GeneratorFilter.h"
#include "GeneratorInterface/CepGenInterface/interface/CepGenEventGenerator.h"
#include "GeneratorInterface/ExternalDecays/interface/ExternalDecayDriver.h"

namespace edm {
template <>
inline GeneratorFilter<gen::CepGenEventGenerator, gen::ExternalDecayDriver>::GeneratorFilter(
const ParameterSet& iConfig)
: hadronizer_(iConfig, consumesCollector()) {
init(iConfig);
}
} // namespace edm

namespace gen {
using CepGenGeneratorFilter = edm::GeneratorFilter<CepGenEventGenerator, gen::ExternalDecayDriver>;
}

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// CepGen-CMSSW interfacing module
// 2022-2024, Laurent Forthomme

#ifndef GeneratorInterface_CepGenInterface_CepGenParametersConverter_h
#define GeneratorInterface_CepGenInterface_CepGenParametersConverter_h

#include "FWCore/ParameterSet/interface/ParameterSet.h"

#include <CepGen/Core/ParametersList.h>

namespace cepgen {
ParametersList fromParameterSet(const edm::ParameterSet& iConfig) {
ParametersList params;
for (const auto& param : iConfig.getParameterNames()) {
const auto cepgen_param = param == "name" ? MODULE_NAME : param;
if (iConfig.existsAs<bool>(param))
params.set(cepgen_param, iConfig.getParameter<bool>(param));
if (iConfig.existsAs<int>(param))
params.set(cepgen_param, iConfig.getParameter<int>(param));
if (iConfig.existsAs<unsigned>(param))
params.set<unsigned long long>(cepgen_param, iConfig.getParameter<unsigned>(param));
if (iConfig.existsAs<double>(param))
params.set(cepgen_param, iConfig.getParameter<double>(param));
if (iConfig.existsAs<std::string>(param))
params.set(cepgen_param, iConfig.getParameter<std::string>(param));
if (iConfig.existsAs<std::vector<double> >(param)) {
const auto& vec = iConfig.getParameter<std::vector<double> >(param);
if (vec.size() == 2)
params.set<Limits>(cepgen_param, Limits{vec.at(0), vec.at(1)});
params.set(cepgen_param, iConfig.getParameter<std::vector<double> >(param));
}
if (iConfig.existsAs<std::vector<std::string> >(param))
params.set(cepgen_param, iConfig.getParameter<std::vector<std::string> >(param));
if (iConfig.existsAs<edm::ParameterSet>(param))
params.set(cepgen_param, fromParameterSet(iConfig.getParameter<edm::ParameterSet>(param)));
}
return params;
}
} // namespace cepgen

#endif
7 changes: 7 additions & 0 deletions GeneratorInterface/CepGenInterface/plugins/BuildFile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<use name="FWCore/Framework"/>
<use name="GeneratorInterface/Core"/>
<use name="GeneratorInterface/CepGenInterface"/>
<use name="GeneratorInterface/ExternalDecays"/>
<library file="CepGenGeneratorFilter.cc" name="GeneratorInterfaceCepGenGenerator">
<flags EDM_PLUGIN="1"/>
</library>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// CepGen-CMSSW interfacing module
// 2022-2024, Laurent Forthomme

#include "FWCore/Framework/interface/MakerMacros.h"
#include "GeneratorInterface/CepGenInterface/interface/CepGenGeneratorFilter.h"

using gen::CepGenGeneratorFilter;
DEFINE_FWK_MODULE(CepGenGeneratorFilter);
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import FWCore.ParameterSet.Config as cms

cepgenOutputModules = cms.untracked.PSet(
# place here all CepGen modules steering for output
# e.g. for a printout of every 1000th event:
#dump = cms.PSet(printEvery = cms.uint32(1000))
)

cepgenPythia6BeamFragmenter = cms.untracked.PSet(
pythia6 = cms.PSet(
maxTrials = cms.int32(10),
seed = cms.int32(42),
preConfiguration = cms.vstring(
'MSTU(21)=1 ! Check on possible errors during program execution',
'MSTU(25)=0 ! No warnings are written',
'MSTJ(22)=2 ! Decay those unstable particles',
'PARJ(71)=10 . ! for which ctau 10 mm',
'MSTP(33)=0 ! no K factors in hard cross sections',
'MSTP(2)=1 ! which order running alphaS',
'MSTP(81)=0 ! multiple parton interactions 1 is Pythia default'
)
)
)
92 changes: 92 additions & 0 deletions GeneratorInterface/CepGenInterface/src/CepGenEventGenerator.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// CepGen-CMSSW interfacing module
// 2022-2024, Laurent Forthomme

#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/StreamID.h"

#include "GeneratorInterface/CepGenInterface/interface/CepGenEventGenerator.h"
#include "GeneratorInterface/CepGenInterface/interface/CepGenParametersConverter.h"

#include <CepGen/Core/Exception.h>
#include <CepGen/Core/RunParameters.h>
#include <CepGen/Event/Event.h>
#include <CepGen/EventFilter/EventExporter.h>
#include <CepGen/EventFilter/EventModifier.h>
#include <CepGen/Generator.h>
#include <CepGen/Modules/EventExporterFactory.h>
#include <CepGen/Modules/EventModifierFactory.h>
#include <CepGen/Modules/ProcessFactory.h>
#include <CepGen/Process/Process.h>
#include <CepGenAddOns/HepMC2Wrapper/HepMC2EventInterface.h>

using namespace gen;

CepGenEventGenerator::CepGenEventGenerator(const edm::ParameterSet& iConfig, edm::ConsumesCollector&& iC)
: BaseHadronizer(iConfig),
proc_params_(cepgen::fromParameterSet(iConfig.getParameter<edm::ParameterSet>("process"))) {
// specify the overall module verbosity
cepgen::utils::Logger::get().setLevel(
static_cast<cepgen::utils::Logger::Level>(iConfig.getUntrackedParameter<int>("verbosity", 0)));

// build the process
edm::LogInfo("CepGenEventGenerator") << "Process to be generated: " << proc_params_ << ".";

const auto modif_mods = cepgen::fromParameterSet(
iConfig.getUntrackedParameter<edm::ParameterSet>("modifierModules", edm::ParameterSet{}));
edm::LogInfo("CepGenEventGenerator") << "Event modifier modules: " << modif_mods << ".";
for (const auto& mod : modif_mods.keys())
modif_modules_.emplace_back(std::make_pair(mod, modif_mods.get<cepgen::ParametersList>(mod)));

const auto output_mods =
cepgen::fromParameterSet(iConfig.getUntrackedParameter<edm::ParameterSet>("outputModules", edm::ParameterSet{}));
edm::LogInfo("CepGenEventGenerator") << "Output modules: " << output_mods << ".";
for (const auto& mod : output_mods.keys())
output_modules_.emplace_back(std::make_pair(mod, output_mods.get<cepgen::ParametersList>(mod)));
}

CepGenEventGenerator::~CepGenEventGenerator() { edm::LogInfo("CepGenEventGenerator") << "Destructor called."; }

bool CepGenEventGenerator::initializeForInternalPartons() {
gen_ = new cepgen::Generator(true /* "safe" mode: start without plugins */);

auto pproc = proc_params_;
{ // little treatment to allow for standard CepGen configurations to be copy-pasted in place
pproc += proc_params_.get<cepgen::ParametersList>("processParameters");
pproc.erase("processParameters");
auto& pkin = pproc.operator[]<cepgen::ParametersList>("kinematics");
pkin += pproc.get<cepgen::ParametersList>("inKinematics");
pproc.erase("inKinematics");
pkin += pproc.get<cepgen::ParametersList>("outKinematics");
pproc.erase("outKinematics");
if (pproc.has<unsigned long long>("mode"))
pkin.set<int>("mode", pproc.get<unsigned long long>("mode"));
}

gen_->runParameters().setProcess(cepgen::ProcessFactory::get().build(pproc));
if (!gen_->runParameters().hasProcess())
throw cms::Exception("CepGenEventGenerator") << "Failed to retrieve a process from the configuration";
for (const auto& mod : modif_modules_) {
auto modifier = cepgen::EventModifierFactory::get().build(mod.first, mod.second);
for (const auto& cfg : mod.second.get<std::vector<std::string> >("preConfiguration"))
modifier->readString(cfg);
for (const auto& cfg : mod.second.get<std::vector<std::string> >("processConfiguration"))
modifier->readString(cfg);
gen_->runParameters().addModifier(std::move(modifier));
}
for (const auto& mod : output_modules_)
gen_->runParameters().addEventExporter(cepgen::EventExporterFactory::get().build(mod.first, mod.second));

edm::LogInfo("CepGenEventGenerator") << "Run parameters:\n" << gen_->runParameters();
const auto xsec = gen_->computeXsection();
xsec_.set_cross_section(xsec, xsec.uncertainty());
runInfo().setInternalXSec(GenRunInfoProduct::XSec(xsec, xsec.uncertainty()));
return true;
}

bool CepGenEventGenerator::generatePartonsAndHadronize() {
event().reset(new HepMC::CepGenEvent(gen_->next()));
event()->set_cross_section(xsec_);
event()->weights().push_back(1.);
return true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// CepGen-CMSSW interfacing module
// 2022-2024, Laurent Forthomme

#include "GeneratorInterface/CepGenInterface/interface/CepGenGeneratorFilter.h"

0 comments on commit 69e7cae

Please sign in to comment.