9#include <generators/modules/fragmentation/FragmentationModule.h>
11#include <generators/evtgen/EvtGenInterface.h>
12#include <generators/utilities/GeneratorConst.h>
14#include <framework/gearbox/Unit.h>
15#include <framework/gearbox/Const.h>
16#include <framework/particledb/EvtGenDatabasePDG.h>
17#include <framework/utilities/FileSystem.h>
21#include <mdst/dataobjects/MCParticleGraph.h>
23#include <framework/logging/Logger.h>
24#include <framework/utilities/IOIntercept.h>
30using namespace Pythia8;
48 addParam(
"ListPYTHIAEvent",
m_listEvent,
"List event record of PYTHIA after hadronization", 0);
55 "PDG Code of the mother particle of the quark pair (default Z0 boson)", 23);
78 statLogCapture.
start();
86 B2WARNING(
"Not all events could be fragmented: " <<
nAll -
nGood <<
" events failed.");
87 B2WARNING(
"Total number of events: " <<
nAll <<
", of these fragmented: " <<
nGood <<
", success-ratio (should be >97%): " << ratio
89 B2WARNING(
"Please contact the generator librarian if the success ratio is below 97%.");
90 B2WARNING(
"Please treat the success-ratio as correction of the effective cross section due to unphysical events.");
101 B2DEBUG(150,
"Initialize PYTHIA8");
109 initLogCapture.
start();
113 (*m_PythiaEvent) = 0;
120 m_Pythia->readString(
"ProcessLevel:all = off");
124 B2FATAL(
"Cannot read Pythia parameter file.");
128#if PYTHIA_VERSION_INTEGER < 8301
130 m_Pythia->setRndmEnginePtr(fragRndm);
132 std::shared_ptr<FragmentationRndm> fragRndm = std::make_shared<FragmentationRndm>();
133 m_Pythia->setRndmEnginePtr(fragRndm);
143 B2INFO(
"Using PYTHIA EvtGen Interface");
146 B2ERROR(
"No global decay file defined, please make sure the parameter 'DecFile' is set correctly");
149 if (defaultDecFile.empty()) {
150 B2WARNING(
"Cannot find default decay file");
151 }
else if (defaultDecFile !=
m_DecFile) {
152 B2INFO(
"Using non-standard DECAY file \"" <<
m_DecFile <<
"\"");
157 evtgen->signalSuffix =
"sig";
186 resetLogCapture.
start();
196 std::map<int, int> indexPYTHIA;
199 std::map<int, int> indexMCGraph;
202 int quarkPosition = 0;
206 for (
int iPart = 0; iPart < nPart; iPart++) {
213 if (pythiaIndex != 0) {
214 indexPYTHIA[
nAdded] = iPart;
215 if (pythiaIndex > 0) quarkPosition = iPart;
221 B2FATAL(
"Invalid number of quarks: " <<
nQuarks <<
" (should be 2)!");
225 B2WARNING(
"No virtual exchange particle given, no PYTHIA FSR in Decays");
228 m_Pythia->forceTimeShower(2, 3, 20.00);
239 eventLogCapture.
start();
245 listLogCapture.
start();
257 decayLogCapture.
start();
264 for (
int iPythiaPart = 0; iPythiaPart <
m_Pythia->event.size(); ++iPythiaPart) {
265 auto oldindex = indexPYTHIA.find(iPythiaPart);
268 if (
m_Pythia->event[iPythiaPart].id() == 90)
continue;
270 if (oldindex == end(indexPYTHIA)) {
276 indexMCGraph[iPythiaPart] = position;
282 if (
m_Pythia->event[iPythiaPart].statusHepMC() < 1)
continue;
285 p->setPDG(
m_Pythia->event[iPythiaPart].id());
288 ROOT::Math::PxPyPzEVector p4(
m_Pythia->event[iPythiaPart].px(),
m_Pythia->event[iPythiaPart].py(),
292 p->setMass(
m_Pythia->event[iPythiaPart].m());
298 p->setValidVertex(
true);
304 if (
m_Pythia->event[iPythiaPart].status() == 51 &&
m_Pythia->event[iPythiaPart].id() == 22) {
309 if (
m_Pythia->event[iPythiaPart].status() == GeneratorConst::FSR_STATUS_CODE &&
m_Pythia->event[iPythiaPart].id() == 22) {
314 if (
m_Pythia->event[iPythiaPart].statusHepMC() == 1) {
319 const int motherid =
m_Pythia->event[iPythiaPart].mother1();
322 auto motherindex = indexMCGraph.find(motherid);
324 if (motherindex != end(indexMCGraph)) {
325 int motheridingraph = indexMCGraph[motherid];
356 const int id = mcParticle.
getPDG();
360 bool isQuark =
false;
361 if (abs(
id) >= 1 && abs(
id) <= 5) isQuark =
true;
364 if (!(isVPho || isQuark))
return 0;
368 B2WARNING(
"Quark already has a daughter!");
373 const double mass = mcParticle.
getMass();
374 const ROOT::Math::XYZVector& p = mcParticle.
getMomentum();
375 const double energy =
sqrt(mass * mass + p.Mag2());
379 m_PythiaEvent->append(
m_quarkPairMotherParticle, -22, 0, 0, 2, 3, 0, 0, p.X(), p.Y(), p.Z(), energy, mass);
382 m_PythiaEvent->append(
id, 23, 1, 0, 0, 0, 101, 0, p.X(), p.Y(), p.Z(), energy, mass, 20.0);
385 m_PythiaEvent->append(
id, 23, 1, 0, 0, 0, 0, 101, p.X(), p.Y(), p.Z(), energy, mass, 20.0);
396 Pythia8::ParticleData* particleData = &pythia->particleData;
397 int nParticles = EvtPDL::entries();
398 for (
int i = 0; i < nParticles; ++i) {
399 EvtId evtgenParticle = EvtPDL::getEntry(i);
405 int pdg = EvtPDL::getStdHep(evtgenParticle);
406 if (pdg <= 10 || (pdg > 20 && pdg <= 100))
408 EvtId evtgenAntiParticle = EvtPDL::chargeConj(evtgenParticle);
409 if (particleData->isParticle(pdg)) {
410 particleData->setAll(pdg,
411 EvtPDL::name(evtgenParticle),
412 EvtPDL::name(evtgenAntiParticle),
413 EvtPDL::getSpinType(evtgenParticle),
414 EvtPDL::chg3(evtgenParticle),
417 EvtPDL::getMeanMass(evtgenParticle),
418 EvtPDL::getWidth(evtgenParticle),
419 EvtPDL::getMinMass(evtgenParticle),
420 EvtPDL::getMaxMass(evtgenParticle),
421 EvtPDL::getctau(evtgenParticle));
423 particleData->addParticle(
425 EvtPDL::name(evtgenParticle),
426 EvtPDL::name(evtgenAntiParticle),
427 EvtPDL::getSpinType(evtgenParticle),
428 EvtPDL::chg3(evtgenParticle),
431 EvtPDL::getMeanMass(evtgenParticle),
432 EvtPDL::getWidth(evtgenParticle),
433 EvtPDL::getMinMass(evtgenParticle),
434 EvtPDL::getMaxMass(evtgenParticle),
435 EvtPDL::getctau(evtgenParticle));
443FragmentationRndm::FragmentationRndm() : Pythia8::RndmEngine()
450 double value = gRandom->Rndm();
static const double speedOfLight
[cm/ns]
static EvtGen * createEvtGen(const std::string &decayFileName, bool coherentMixing)
Create and initialize an EvtGen instance:
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
EvtGenDecays * evtgen
EvtGen decay engine inside PYTHIA8.
int nGood
number of events with successful fragmentation.
FragmentationModule()
Constructor.
void loadEvtGenParticleData(Pythia8::Pythia *pythia)
Load EvtGen particle data.
bool m_coherentMixing
decay the B0-B0bar coherently.
int nVpho
number of virtual exchange particles.
virtual void initialize() override
Initialize the module.
virtual void event() override
Event method (process events)
Pythia8::Pythia * m_Pythia
Pythia generator.
StoreArray< MCParticle > m_mcparticles
store array for the MCParticles
virtual ~FragmentationModule()
Destructor.
virtual void terminate() override
terminate the module
Pythia8::Event * m_PythiaEvent
Pythia event.
int addParticleToPYTHIA(const MCParticle &mcParticle)
Add particle to Pythia event.
std::string m_DecFile
EvtGen decay file.
int m_useEvtGen
use EvtGen for some decays.
int nAll
number of events created.
std::string m_UserDecFile
User EvtGen decay file.
std::string m_particleList
The name of the MCParticle collection.
int nQuarks
number of quarks.
MCParticleGraph mcParticleGraph
An instance of the MCParticle graph.
std::string m_parameterfile
Module parameters.
std::vector< int > m_additionalPDGCodes
Additional particles used in Pythia.
int nAdded
number of added particles.
int m_quarkPairMotherParticle
PDG Code of the mother particle of the quark pair.
int m_listEvent
list event generated by PYTHIA.
Minimal class for external random generator to be used in PYTHIA.
double flat()
flat random generator.
bool start()
Start intercepting the output.
Capture stdout and stderr and convert into log messages.
bool finish()
Finish the capture and emit the message if output has appeard on stdout or stderr.
@ c_Error
Error: for things that went wrong and have to be fixed.
@ c_Debug
Debug: for code development.
@ c_Warning
Warning: for potential problems that the user should pay attention to.
Class to represent Particle data in graph.
@ c_checkCyclic
Check for cyclic dependencies.
@ c_clearParticles
Clear the particle list before adding the graph.
@ c_setDecayInfo
Set decay time and vertex.
A Class to store the Monte Carlo particle information.
@ c_IsFSRPhoton
bit 7: Particle is from final state radiation
@ c_IsPHOTOSPhoton
bit 8: Particle is an radiative photon from PHOTOS
@ c_PrimaryParticle
bit 0: Particle is primary particle.
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
float getMass() const
Return the particle mass in GeV.
int getPDG() const
Return PDG code of particle.
ROOT::Math::XYZVector getMomentum() const
Return momentum.
void setDescription(const std::string &description)
Sets the description of the module.
void setReturnValue(int value)
Sets the return value for this module as integer.
static const double mm
[millimeters]
A class to perform decays via the external EvtGen decay program, see http://evtgen....
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.