9#include <framework/gearbox/Unit.h>
10#include <framework/gearbox/Const.h>
11#include <framework/logging/Logger.h>
12#include <framework/particledb/EvtGenDatabasePDG.h>
13#include <framework/utilities/FileSystem.h>
14#include <generators/evtgen/EvtGenInterface.h>
15#include <mdst/dataobjects/MCParticleGraph.h>
16#include <generators/evtgen/EvtGenModelRegister.h>
22#include <EvtGenExternal/EvtExternalGenList.hh>
23#include <EvtGenBase/EvtAbsRadCorr.hh>
24#include <EvtGenBase/EvtCPUtil.hh>
25#include <EvtGenBase/EvtDecayTable.hh>
26#include <EvtGenBase/EvtDecayBase.hh>
27#include <EvtGenBase/EvtParticleFactory.hh>
28#include <EvtGenBase/EvtPDL.hh>
29#include <EvtGenBase/EvtRandom.hh>
38 EvtDecayTable* evtDecayTable = EvtDecayTable::getInstance();
39 for (
unsigned int i = 0; i < EvtPDL::entries(); ++i) {
40 for (
int j = 0; j < evtDecayTable->getNMode(i); ++j) {
41 delete evtDecayTable->getDecay(i, j);
52 initLogCapture.
start();
61 EvtExternalGenList genList{
false};
62 EvtAbsRadCorr* radCorrEngine = genList.getPhotosModel();
63 list<EvtDecayBase*> modelList = genList.getListOfModels();
64 extraModels.insert(extraModels.end(), modelList.begin(), modelList.end());
69 auto mixingMode = EvtCPUtil::Incoherent;
71 mixingMode = EvtCPUtil::Coherent;
73 B2WARNING(
"Evtgen has been set to decay the B mesons incoherently. This is useful as a workaround only to generate Y(5S, 6S) -> BBar for QCD studies.");
74 B2WARNING(
"If you are generating Y(4S) events, you _really_ must use the coherent decay mode.");
78 radCorrEngine, &extraModels, mixingMode);
85 const std::string& userFileName,
const bool coherentMixing)
87 B2DEBUG(20,
"Begin initialisation of EvtGen Interface.");
92 initLogCapture.
start();
96 if (!userFileName.empty()) {
101 if (parentParticle !=
"") {
107 B2DEBUG(20,
"End initialisation of EvtGen Interface.");
114static void addInitialParticle(
MCParticleGraph& mpg,
int pdg, ROOT::Math::PxPyPzEVector p4)
133 const std::string& inclusiveParticle)
135 EvtId inclusiveParticleID, inclusiveAntiParticleID;
138 B2FATAL(
"Parent particle is not initialized.");
141 ROOT::Math::PxPyPzEVector pParentParticle = initial.
getHER() + initial.
getLER();
143 ROOT::Math::XYZVector pPrimaryVertex = initial.
getVertex();
145 EvtVector4R pinit(pParentParticle.E(), pParentParticle.X(), pParentParticle.Y(), pParentParticle.Z());
147 if (inclusiveType != 0) {
148 inclusiveParticleID = EvtPDL::getId(inclusiveParticle);
149 if (inclusiveParticleID.getId() < 0)
150 B2FATAL(
"Incorrect inclusive particle " << inclusiveParticle);
151 inclusiveAntiParticleID = EvtPDL::chargeConj(inclusiveParticleID);
152 if (inclusiveAntiParticleID.getId() < 0) {
153 B2FATAL(
"Cannot find the charge-conjugate particle for "
154 << inclusiveParticle);
158 bool we_got_inclusive_particle =
false;
167 rho.setDiag(
m_parent->getSpinStates());
168 rho.set(1, 1, EvtComplex(0.0, 0.0));
171 double alpha = herCMS.Phi(), beta = herCMS.Theta(), gamma = 0;
172 m_parent->setSpinDensityForwardHelicityBasis(rho, alpha, beta, gamma);
178 if (inclusiveType != 0) {
185 if (p->getId() == inclusiveParticleID ||
186 (inclusiveType == 2 && p->getId() == inclusiveAntiParticleID)) {
187 we_got_inclusive_particle =
true;
193 if (!we_got_inclusive_particle) {
198 we_got_inclusive_particle =
true;
200 }
while (!we_got_inclusive_particle);
205 addInitialParticle(graph, 11, initial.
getHER());
206 addInitialParticle(graph, -11, initial.
getLER());
221 ROOT::Math::PxPyPzEVector momentum = parent.
get4Vector();
222 ROOT::Math::XYZVector vertex = parent.
getVertex();
223 EvtVector4R pinit(momentum.E(), momentum.X(), momentum.Y(), momentum.Z());
227 parent.
setDecayTime(-std::numeric_limits<float>::infinity());
229 id = EvtPDL::evtIdFromStdHep(pdg);
230 m_parent = EvtParticleFactory::particleFactory(
id, pinit);
246 const int existingParticles = graph.
size();
254 typedef pair<MCParticleGraph::GraphParticle*, EvtParticle*> halfFamily;
255 halfFamily currFamily;
256 queue < halfFamily > heritancesQueue;
258 for (uint idaughter = 0; idaughter < top->getNDaug(); idaughter++) {
259 currFamily.first = p;
260 currFamily.second = top->getDaug(idaughter);
261 heritancesQueue.push(currFamily);
265 while (!heritancesQueue.empty()) {
266 currFamily = heritancesQueue.front();
267 heritancesQueue.pop();
270 EvtParticle* currDaughter = currFamily.second;
279 int nGrandChildren = currDaughter->getNDaug();
281 if (nGrandChildren == 0)
284 for (
int igrandchild = 0; igrandchild < nGrandChildren; igrandchild++) {
285 currFamily.first = graphDaughter;
286 currFamily.second = currDaughter->getDaug(igrandchild);
287 heritancesQueue.push(currFamily);
292 return graph.
size() - existingParticles;
297 ROOT::Math::XYZVector pPrimaryVertex,
double timeOffset)
302 gParticle->
setMass(eParticle->mass());
303 gParticle->
setPDG(EvtPDL::getStdHep(eParticle->getId()));
305 EvtVector4R EvtP4 = eParticle->getP4Lab();
306 ROOT::Math::PxPyPzEVector p4(EvtP4.get(1), EvtP4.get(2), EvtP4.get(3), EvtP4.get(0));
309 EvtVector4R Evtpos = eParticle->get4Pos();
312 pVertex = pVertex + pPrimaryVertex;
319 if (eParticle->getAttribute(
"FSR")) {
static const double speedOfLight
[cm/ns]
static const double electronMass
electron mass
static EvtGenDatabasePDG * Instance()
Instance method that loads the EvtGen table.
void WriteEvtGenTable(std::ostream &out)
Write current database as EvtGen table to a stream.
int simulateEvent(MCInitialParticles initial, int inclusiveType, const std::string &inclusiveParticle)
Generate a single event.
int simulateDecay(MCParticleGraph &graph, MCParticleGraph::GraphParticle &parent)
Simulate a particle decay.
EvtGen * m_Generator
Variable needed for EvtGen generator.
~EvtGenInterface()
Destructor.
IOIntercept::OutputToLogMessages m_logCaptureDebug
Capture EvtGen log and transform into basf2 logging as B2DEBUG messages.
int setup(const std::string &decayFileName, const std::string &parentParticle, const std::string &userFileName=std::string(""), bool coherentMixing=true)
Setup evtgen with the given decay files
static EvtGenFwRandEngine m_eng
Variable needed for random generator.
EvtParticle * m_parent
Variable needed for parent particle.
static EvtGen * createEvtGen(const std::string &decayFileName, bool coherentMixing)
Create and initialize an EvtGen instance:
EvtId m_ParentParticle
Variable needed for parent particle ID.
bool m_ParentInitialized
Whether parent particle is initialized.
void updateGraphParticle(EvtParticle *eParticle, MCParticleGraph::GraphParticle *gParticle, ROOT::Math::XYZVector pPrimaryVertex, double timeOffset=0)
Copy parameters from EvtParticle to MCParticle.
int addParticles2Graph(EvtParticle *particle, MCParticleGraph &graph, ROOT::Math::XYZVector pPrimaryVertex, MCParticleGraph::GraphParticle *parent, double timeOffset=0)
Convert EvtParticle structure to flat MCParticle list.
Helper file to create a temporary file and ensure deletion if object goes out of scope.
std::string getName() const
get filename of the temporary file
bool start()
Start intercepting the output.
Capture stdout and stderr and convert into log messages.
void setIndent(const std::string &indent)
Set the indent for each line of the output, default is the supplied name + ": "
bool finish()
Finish the capture and emit the message if output has appeard on stdout or stderr.
@ c_Info
Info: for informational messages, e.g.
This class contains the initial state for the given event.
const ROOT::Math::PxPyPzEVector & getHER() const
Get 4vector of the high energy beam.
ROOT::Math::PxPyPzEVector getBoostedHER() const
Get the 4-vector of electron beam in CM system obtained by pure boost.
const ROOT::Math::PxPyPzEVector & getLER() const
Get 4vector of the low energy beam.
const ROOT::Math::XYZVector & getVertex() const
Get the position of the collision.
Class to represent Particle data in graph.
void decaysInto(GraphParticle &daughter)
Tells the graph that this particle decays into daughter.
Class to build, validate and sort a particle decay chain.
@ c_checkCyclic
Check for cyclic dependencies.
@ c_setDecayInfo
Set decay time and vertex.
size_t size() const
Return the number of particles in the graph.
void generateList(const std::string &name="", int options=c_setNothing)
Generates the MCParticle list and stores it in the StoreArray with the given name.
@ c_Initial
bit 5: Particle is initial such as e+ or e- and not going to Geant4
@ 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.
void setDecayTime(float time)
Set decay time.
void setMass(float mass)
Set particle mass.
void addStatus(unsigned short int bitmask)
Add bitmask to current status.
ROOT::Math::XYZVector getVertex() const
Return production vertex position, shorthand for getProductionVertex().
void setValidVertex(bool valid)
Set indication wether vertex and time information is valid or just default.
void setProductionVertex(const ROOT::Math::XYZVector &vertex)
Set production vertex position.
ROOT::Math::PxPyPzEVector get4Vector() const
Return 4Vector of particle.
void setPDG(int pdg)
Set PDG code of the particle.
int getPDG() const
Return PDG code of particle.
float getProductionTime() const
Return production time in ns.
void set4Vector(const ROOT::Math::PxPyPzEVector &p4)
Sets the 4Vector of particle.
void setStatus(unsigned short int status)
Set Status code for the particle.
void setProductionTime(float time)
Set production time.
static const double mm
[millimeters]
static std::list< EvtDecayBase * > getModels()
Return a list of models.
GraphParticle & addParticle()
Add new particle to the graph.
Abstract base class for different kinds of events.