24 std::string s_pythia_stream{
"PYTHIA8_INIT"};
29#define PYTHIA8_NWEIGHTS nWeights
30#define PYTHIA8_WEIGHT weight
31#define PYTHIA8_WLABEL weightLabel
32#define PYTHIA8_CONVERSION 1.0
34#ifdef PYTHIA_VERSION_INTEGER
35 #undef PYTHIA8_NWEIGHTS
38 #if PYTHIA_VERSION_INTEGER > 8303
39 #define PYTHIA8_NWEIGHTS nWeightGroups
41 #define PYTHIA8_NWEIGHTS nVariationGroups
43 #define PYTHIA8_WEIGHT getGroupWeight
44 #define PYTHIA8_WLABEL getGroupName
53std::string py8version()
55 static const std::string incdir (PY8INCLUDE_DIR);
56 std::string::size_type pos = incdir.find (
"/pythia8/");
57 if (pos == std::string::npos)
return "";
59 std::string::size_type pos2 = incdir.find (
"/", pos);
60 if (pos2 == std::string::npos) pos2 = incdir.size();
61 return incdir.substr (pos, pos2-pos);
95 #ifndef PYTHIA8_3SERIES
111 m_runinfo = std::make_shared<HepMC3::GenRunInfo>();
113 struct HepMC3::GenRunInfo::ToolInfo generator={std::string(
"Pythia8"),py8version(),std::string(
"Used generator")};
114 m_runinfo->tools().push_back(std::move(generator));
120 s_pythia_stream =
"PYTHIA8_INIT";
128 m_pythia->readString(
"Tune:pp = 5");
132 m_pythia->readString(
"PDF:pSet= LHAPDF6:cteq6l1");
135 m_pythia->readString(
"Next:numberShowEvent = 0");
138 m_pythia->settings.addFlag(
"AthenaPythia8ToHepMC:print_inconsistency",
true);
150 bool canSetHook =
true;
151 if (hook ==
"SuppressSmallPT") {
167 m_pythia->settings.addParm(param.first, param.second,
false,
false, 0., 0.);
171 m_pythia->settings.addMode(param.first, param.second,
false,
false, 0., 0.);
175 m_pythia->settings.addFlag(param.first, param.second);
179 m_pythia->settings.addWord(param.first, param.second);
184 ATH_MSG_ERROR(
"Unable to retrieve Athena Tool for custom Pythia processing");
185 return StatusCode::FAILURE;
189 if(status != StatusCode::SUCCESS)
return status;
196 if(cmd.compare(
"")==0)
continue;
197 else if (cmd.find(
"Beams:id") != std::string::npos ) {
198 ATH_MSG_ERROR(
"With command '" << cmd <<
"' you are trying to set a beam different from p: please use the Beam1/Beam2 properties instead:");
201 return StatusCode::FAILURE;
203 else if (cmd.find(
"Beams:frameType") != std::string::npos ) {
205 ATH_MSG_WARNING(
" Found an explicit 'Beams:frameType' command: this will override transform beams momenta/energy parameters, regardless of its requested value. ");
211 ATH_MSG_ERROR(
"Pythia could not understand the command '"<< cmd<<
"'");
212 return StatusCode::FAILURE;
222 if(beam1 == 0 || beam2 == 0){
224 return StatusCode::FAILURE;
231 ATH_MSG_INFO(
" !!!!!!!!!!!! WARNING ON PYTHIA RANDOM NUMBERS !!!!!!!!!! ");
232 ATH_MSG_INFO(
" THE ATHENA SERVICE AthRNGenSvc IS USED.");
233 ATH_MSG_INFO(
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ");
238#if PYTHIA_VERSION_INTEGER >= 8310
243 s_pythia_stream =
"PYTHIA8";
245 ATH_MSG_INFO(
" !!!!!!!!!!!! WARNING ON PYTHIA RANDOM NUMBERS !!!!!!!!!! ");
246 ATH_MSG_INFO(
" THE STANDARD PYTHIA8 RANDOM NUMBER SERVICE IS USED.");
247 ATH_MSG_INFO(
" THE ATHENA SERVICE AthRNGSvc IS ***NOT*** USED.");
248 ATH_MSG_INFO(
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ");
259 std::vector<std::string> resonanceArgs;
261 for (
auto&& part : std::views::split(
m_userResonances.value(),
':')) resonanceArgs.emplace_back(part.begin(), part.end());
262 if(resonanceArgs.size() != 2){
263 ATH_MSG_ERROR(
"Cannot Understand UserResonance job option!");
264 ATH_MSG_ERROR(
"You should specify it as a 'name:id1,id2,id3...'");
265 ATH_MSG_ERROR(
"Where name is the name of your UserResonance, and id1,id2,id3 are a comma separated list of PDG IDs to which it is applied");
268 std::vector<std::string> resonanceIds;
269 for (
auto&& part : std::views::split(resonanceArgs.back(),
',')) resonanceIds.emplace_back(part.begin(), part.end());
270 if(resonanceIds.size()==0){
271 ATH_MSG_ERROR(
"You did not specifiy any PDG ids to which your user resonance width should be applied!");
272 ATH_MSG_ERROR(
"You should specify a list as 'name:id1,id2,id3...'");
273 ATH_MSG_ERROR(
"Where name is the name of your UserResonance, and id1,id2,id3 are a comma separated list of PDG IDs to which it is applied");
277 for(std::vector<std::string>::const_iterator sId = resonanceIds.begin();
278 sId != resonanceIds.end(); ++sId){
280 auto result = std::from_chars(sId->data(), sId->data() + sId->size(), idResIn);
281 if (result.ec != std::errc()) {
288#if PYTHIA_VERSION_INTEGER >= 8310
289 m_pythia->setResonancePtr(resonance);
291 m_pythia->setResonancePtr(resonance.get());
307 ATH_MSG_ERROR(
"Both LHE file and user process have been specified");
308 ATH_MSG_ERROR(
"LHE input does not make sense with a user process!");
312 canInit = canInit &&
m_pythia->readString(
"Beams:frameType = 4");
320 canInit = canInit &&
m_pythia->readString(
"Beams:frameType = 1");
323 canInit = canInit &&
m_pythia->readString(
"Beams:idA = " + std::to_string(beam1));
324 canInit = canInit &&
m_pythia->readString(
"Beams:idB = " + std::to_string(beam2));
328#if PYTHIA_VERSION_INTEGER >= 8310
340 StatusCode returnCode = StatusCode::SUCCESS;
343 m_pythia->settings.writeFile(
"Settings_before.log",
true);
350 returnCode = StatusCode::FAILURE;
355 m_pythia->settings.writeFile(
"Settings_after.log",
true);
363 m_pythiaToHepMC.set_print_inconsistency(
m_pythia->settings.flag(
"AthenaPythia8ToHepMC:print_inconsistency") );
378 const EventContext& ctx = Gaudi::Hive::currentContext();
388 StatusCode returnCode = StatusCode::SUCCESS;
393 ATH_MSG_ERROR(
"Exceeded the max number of consecutive event failures.");
394 returnCode = StatusCode::FAILURE;
404 if(stat != StatusCode::SUCCESS) returnCode = stat;
413 double eventWeight =
m_pythia->info.mergingWeight()*
m_pythia->info.weight();
416 if(returnCode != StatusCode::FAILURE &&
418 (std::abs(eventWeight) < std::numeric_limits<float>::min() ||
422 }
else if ( std::abs(eventWeight) < std::numeric_limits<float>::min() &&
423 std::abs(eventWeight) > std::numeric_limits<double>::min() ){
424 ATH_MSG_WARNING(
"Found event weight " << eventWeight <<
" between the float and double precision limits. Rejecting event.");
451 ATH_MSG_ERROR(
"Something wrong with this event - it contains fewer than 2 particles!");
453 return StatusCode::FAILURE;
460 auto evtlhe = std::make_shared<HepMC::GenEvent>();
462 auto extra = std::make_shared<HepMC::ShortEventAttribute>(evtlhe.get());
463 evt->add_attribute(HepMCStr::LHERecord, extra);
468 ATH_MSG_DEBUG(
"PDFinfo id1:" << evt->pdf_info()->parton_id[0]);
469 ATH_MSG_DEBUG(
"PDFinfo id2:" << evt->pdf_info()->parton_id[1]);
472 ATH_MSG_DEBUG(
"PDFinfo scalePDF:" << evt->pdf_info()->scale);
473 ATH_MSG_DEBUG(
"PDFinfo pdf1:" << evt->pdf_info()->pdf_id[0]);
474 ATH_MSG_DEBUG(
"PDFinfo pdf2:" << evt->pdf_info()->pdf_id[1]);
477 ATH_MSG_DEBUG(
"No PDF information available in HepMC::GenEvent!");
485 return StatusCode::SUCCESS;
495#ifndef PYTHIA8_304SERIES
498 if (hook->canEnhanceEmission()) {
507 std::map<std::string,double> fWeights;
511 size_t atlas_specific_weights = 1;
512 fWeights[
"Default"]=eventWeight;
536 std::vector<std::string>::const_iterator
id =
m_weightIDs.begin()+atlas_specific_weights;
539 if(
m_pythia->info.getWeightsDetailedSize() != 0){
540 for(std::map<std::string, Pythia8::LHAwgt>::const_iterator wgt =
m_pythia->info.rwgt->wgts.begin();
541 wgt !=
m_pythia->info.rwgt->wgts.end(); ++wgt){
546 if(*
id != wgt->first){
547 ATH_MSG_ERROR(
"Mismatch in LHE3 weight id. Found "<<wgt->first<<
", expected "<<*
id);
548 return StatusCode::FAILURE;
553 std::map<std::string, Pythia8::LHAweight>::const_iterator weightName =
m_pythia->info.init_weights->find(wgt->first);
554 if(weightName !=
m_pythia->info.init_weights->end()){
567 for(
int iw = 1; iw <
m_pythia->info.PYTHIA8_NWEIGHTS(); ++iw){
583 fWeights[
"EXTRA_bare_LHE_weight"]=(-10.0)*
m_pythia->info.eventWeightLHEF;
592 std::map<std::string, Pythia8::LHAweight>::const_iterator weight =
m_pythia->info.init_weights->find(
id);
601 ATH_MSG_ERROR(
"Something wrong when building list of weight names: " <<
m_weightNames.size() <<
" vs "<< fWeights.size() <<
", exiting ...");
602 return StatusCode::FAILURE;
607 if (!evt->run_info()) {
614 evt->weights().push_back(1.0);
618 evt->set_units(HepMC3::Units::MEV, HepMC3::Units::MM);
620 evt->weights().resize(fWeights.size(), 1.0);
621 for (
const auto & w: fWeights) {
622 evt->weight(w.first)=w.second;
625 auto beams=evt->beams();
626 ATH_MSG_DEBUG(
" Energy of the beams " << beams[0]->momentum().e() );
633 return StatusCode::SUCCESS;
642 Pythia8::Info info =
m_pythia->info;
643 double xs = info.sigmaGen();
646 const double accfactor =
m_nMerged / info.nAccepted();
647 ATH_MSG_DEBUG(
"Multiplying cross-section by CKKWL merging acceptance of "<<
m_nMerged <<
"/" <<info.nAccepted() <<
" = " << accfactor
648 <<
": " << xs <<
" -> " << xs*accfactor);
655 std::cout <<
"Using FxFx cross section recipe: xs = "<<
m_sigmaTotal <<
" / " << 1e9*info.nTried() << std::endl;
660 ATH_MSG_DEBUG(
"Multiplying cross-section by Pythia Modifier tool factor " << xsmod );
666 std::cout <<
"MetaData: cross-section (nb)= " << xs <<std::endl;
667 std::cout <<
"MetaData: generator= Pythia 8." << std::string(py8version()) <<std::endl;
670 std::cout<<
"MetaData: weights = ";
672 std::cout<<std::endl;
676 if (info.nTried()>0)
ATH_MSG_INFO(
"Pythia8 efficiency (nAccepted/nTried %) = " << info.nAccepted()*100./info.nTried());
677 else ATH_MSG_INFO(
"Pythia8 efficiency cannot be computed, nTried <=0");
686 return StatusCode::SUCCESS;
696 return s_pythia_stream;
703 std::string foundpath =
"";
714#ifdef PYTHIA8_NWEIGHTS
715 #undef PYTHIA8_NWEIGHTS
716 #undef PYTHIA8_WEIGHT
717 #undef PYTHIA8_WLABEL
718 #undef PYTHIA8_CONVERSION
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
std::string PathResolverFindCalibDirectory(const std::string &logical_file_name)
#define PYTHIA8_CONVERSION
#define PYTHIA8_PTRWRAP(A)
GenModule(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
CLHEP::HepRandomEngine * getRandomEngineDuringInitialize(const std::string &streamName, unsigned long int randomSeedOffset, unsigned int conditionsRun=1, unsigned int lbn=1) const
IntegerProperty m_randomSeed
Seed for random number engine.
std::shared_ptr< HepMC3::GenRunInfo > m_runinfo
The run info for HepMC3.
static std::map< std::string, T > & userSettings()
static UserHooks * create(const std::string &hookName)
static std::shared_ptr< Sigma2Process > create(const std::string &procName)
static std::shared_ptr< ResonanceWidths > create(const std::string &name, int pdgid)
Call this with the name of the ResonanceWidth and PDG ID to which it will be applied e....
bool m_override_transform_beamenergy
virtual StatusCode genInitialize()
For initializing the generator, if required.
BooleanProperty m_sameAlphaSAsMPI
virtual StatusCode fillWeights(HepMC::GenEvent *evt)
virtual StatusCode fillEvt(HepMC::GenEvent *evt)
For filling the HepMC event object.
StringProperty m_userProcess
BooleanProperty m_useReseed
static std::string xmlpath()
DoubleProperty m_numberAlphaS
Pythia8::SuppressSmallPT * m_SuppressSmallPT
unsigned int m_failureCount
DoubleProperty m_collisionEnergy
BooleanProperty m_computeEfficiency
std::vector< std::shared_ptr< Pythia8::ResonanceWidths > > m_userResonancePtrs
std::shared_ptr< Pythia8::Sigma2Process > m_procPtr
BooleanProperty m_saveLHE
HepMC::Pythia8ToHepMC m_pythiaToHepMC
PublicToolHandle< IPythia8Custom > m_athenaTool
StringProperty m_userResonances
virtual StatusCode callGenerator()
For calling the generator on each iteration of the event loop.
BooleanProperty m_doFxFxXS
std::vector< long int > m_seeds
std::vector< std::string > m_showerWeightNames
std::vector< std::string > m_weightIDs
DoubleProperty m_pt0timesMPI
std::vector< std::string > m_weightNames
int m_internal_event_number
static const std::string & pythia_stream()
std::shared_ptr< customRndm > m_atlasRndmEngine
double pythiaVersion() const
StringArrayProperty m_userHooks
virtual StatusCode genFinalize()
For finalising the generator, if required.
std::unique_ptr< Pythia8::Pythia > m_pythia
std::map< std::string, PDGID > m_particleIDs
BooleanProperty m_doCKKWLAcceptance
UnsignedIntegerProperty m_maxFailures
BooleanProperty m_useRndmGenSvc
StringProperty m_particleDataFile
std::vector< UserHooksPtrType > m_userHooksPtrs
StringArrayProperty m_showerWeightNamesProp
StringProperty m_outputParticleDataFile
StringArrayProperty m_commands
Pythia8_i(const std::string &name, ISvcLocator *pSvcLocator)
void calculateSeedsMC21(long *seeds, const std::string &algName, uint64_t ev, uint64_t run, uint64_t offset=0)
Set the random seed using a string (e.g.
void set_random_states(GenEvent *e, std::vector< long int > &a)
HepMC3::GenEvent GenEvent
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)