Belle II Software development
GeneratedVertexDisplacerModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <generators/modules/GeneratedVertexDisplacerModule.h>
10#include <framework/core/ModuleParam.templateDetails.h>
11#include <framework/particledb/EvtGenDatabasePDG.h>
12
13
14using namespace Belle2;
15using namespace std;
16
17//-----------------------------------------------------------------
18// Register the Module
19//-----------------------------------------------------------------
20REG_MODULE(GeneratedVertexDisplacer);
21
22//-----------------------------------------------------------------
23// Implementation
24//-----------------------------------------------------------------
25
27{
28 // Set module properties
30 R"DOC(Takes a list of PDG values and lifetime parameters to displace the vertex of MCParticles with matching PDG value corresponding to the given lifetime parameter. Can be used between generator and the detector simulation. NOTE: this module only works properly for particles with 0 lifetime.)DOC");
31
32 // Parameter definitions
33 addParam("lifetimeOption", m_lifetimeOption,
34 "Set the lifetime option, either 'fixed', 'flat' or 'exponential'. Option is set globally.", string("fixed"));
35 addParam("lifetime", m_lifetime,
36 "Set the numerical value of the lifetime c*tau in units of [cm]. Example: (lifetime_1, lifetime_2, ... ,lifetime_N). Lifetime_X is set for PDG_X.",
37 std::vector<float> {0});
38 addParam("pdgVal", m_pdgVals,
39 "PDG values of MCParticles that should be displaced. Subsequent daughters of these will be displaced accordingly. Example: (PDG_1, PDG_2, ... , PDG_N). PDG_X corresponds to lifetime_X.",
40 std::vector<int> { -999});
41 addParam("maxDecayTime", m_maxDecayTime,
42 "Set the maximal allowed decay time in c*tau [cm] for the option 'flat'. The 'exponential' option is not bound. Default 300cm.",
43 static_cast<float>(300));
44 addParam("ctau", m_ctau,
45 "Input unit option. True (default): module expects lifetime as ctau [cm]. False: lifetime as tau [ns].",
46 true);
47
48}
49
50
52{
53
54 B2DEBUG(0, "Initialize GeneratedVertexDisplacerModule");
55 m_mcparticles.isRequired(m_particleList);
56
57 if (m_pdgVals.size() != m_lifetime.size()) {
58 B2FATAL("List of PDG values and lifetime parameters have different sizes. Specify a lifetime for each PDG value.");
59 }
60
61 // Module does not work properly for particles with finite lifetime
63 for (auto aPdgVal : m_pdgVals) {
64 auto particle = evtGenDB->GetParticle(aPdgVal);
65 if (not particle) B2FATAL("Particle pdg code = " << aPdgVal << " not found in EvtGenDatabasePDG.");
66 if (particle->Lifetime() != 0) B2FATAL("Particle pdg code = " << aPdgVal <<
67 " has non-zero lifetime! Module only works for 0 lifetime!");
68 }
69
70 if ((m_lifetimeOption.compare("fixed") != 0) && (m_lifetimeOption.compare("flat") != 0)
71 && (m_lifetimeOption.compare("exponential") != 0)) {
72 B2FATAL("Lifetime option must be 0 (fixed), 1 (flat) or 2 (exponential).");
73 }
74}
75
76
78{
79
80 if (m_mcparticles.getEntries() < 1) {
81 B2WARNING("MC particle container empty. Calling next event.");
82 return;
83 }
84
85 for (int mcp_index = 0; mcp_index < m_mcparticles.getEntries(); mcp_index++) {
86
87 MCParticle& mcp = *m_mcparticles[mcp_index];
88
90
91 int mcp_pdg = mcp.getPDG();
92
93 for (unsigned int param_index = 0; param_index < m_pdgVals.size(); param_index++) {
94 if (m_pdgVals.at(param_index) == mcp_pdg) {
95 B2DEBUG(0, "Displacing Vertex of particle with pdg_id: " << mcp_pdg << " with lifetime: " << m_lifetime.at(
96 param_index) << " and option: " << m_lifetimeOption);
97 displace(mcp, m_lifetime.at(param_index));
98 B2DEBUG(0, "new vertex (x,y,z) at:" << "(" << mcp.getDecayVertex().X() << "," << mcp.getDecayVertex().Y() << "," <<
99 mcp.getDecayVertex().Z() << ")" << " with decaylength=" << std::sqrt(std::pow(mcp.getDecayVertex().X(),
100 2) + std::pow(mcp.getDecayVertex().Y(), 2) + std::pow(mcp.getDecayVertex().Z(), 2))) ;
101 }
102 }
103 }
104}
105
106
108{
109 ROOT::Math::PxPyPzEVector* displacementVector = new ROOT::Math::PxPyPzEVector();
110 getDisplacement(particle, lifetime, *displacementVector);
111
112 ROOT::Math::XYZVector newDecayVertex = particle.getProductionVertex();
113 newDecayVertex.SetX(newDecayVertex.X() + displacementVector->X());
114 newDecayVertex.SetY(newDecayVertex.Y() + displacementVector->Y());
115 newDecayVertex.SetZ(newDecayVertex.Z() + displacementVector->Z());
116
117 particle.setDecayVertex(newDecayVertex);
118 particle.setDecayTime(particle.getProductionTime() + displacementVector->T());
119 particle.setValidVertex(true);
120
121 // displace direct daughters
122 if (particle.getNDaughters()) {
123 displaceDaughter(*displacementVector, particle.getDaughters());
124 }
125
126 delete displacementVector;
127}
128
129
130void GeneratedVertexDisplacerModule::displaceDaughter(ROOT::Math::PxPyPzEVector& motherDisplacementVector,
131 std::vector<MCParticle*> daughters)
132{
133 for (unsigned int daughter_index = 0; daughter_index < daughters.size(); daughter_index++) {
134
135 MCParticle* daughter_mcp = daughters.at(daughter_index);
136 int daughter_mcpArrayIndex = daughter_mcp->getArrayIndex();
137
138 // getDaughters returns a copied list, need to change parameters of the original particle in the MCParticle StoreArray.
139 MCParticle& mcp = *m_mcparticles[daughter_mcpArrayIndex];
140 mcp.setProductionVertex(mcp.getProductionVertex() + motherDisplacementVector.Vect());
141 mcp.setProductionTime(mcp.getProductionTime() + motherDisplacementVector.T());
142 mcp.setValidVertex(true);
143
144 // Displace subsequent daughters
145 if (daughter_mcp->getNDaughters()) {
146 displaceDaughter(motherDisplacementVector, daughter_mcp->getDaughters());
147 }
148 }
149}
150
151
153 const MCParticle& particle, float lifetime, ROOT::Math::PxPyPzEVector& displacement)
154{
155 ROOT::Math::PxPyPzEVector fourVector_mcp = particle.get4Vector();
156 float decayLength_mcp = 0;
157 if (!m_ctau) lifetime *= Const::speedOfLight;
158
159 if (m_lifetimeOption.compare("fixed") == 0) decayLength_mcp = lifetime;
160 else if (m_lifetimeOption.compare("flat") == 0) decayLength_mcp = gRandom->Uniform(0, m_maxDecayTime);
161 else {
162 decayLength_mcp = -1 * std::log(gRandom->Uniform(0, 1.)) * lifetime * fourVector_mcp.Gamma() * fourVector_mcp.Beta();
163
164 if (!particle.getMass()) {
165 B2WARNING("Displacing a particle with zero mass. Forcing Gamma=1 for the decay time.");
166 decayLength_mcp = -1 * std::log(gRandom->Uniform(0, 1.)) * lifetime;
167 }
168 }
169
170 float pMag = fourVector_mcp.P();
171 displacement.SetPx(decayLength_mcp * fourVector_mcp.X() / pMag);
172 displacement.SetPy(decayLength_mcp * fourVector_mcp.Y() / pMag);
173 displacement.SetPz(decayLength_mcp * fourVector_mcp.Z() / pMag);
174 displacement.SetE(decayLength_mcp / (Const::speedOfLight * fourVector_mcp.Beta()));
175}
176
177
182
183
static const double speedOfLight
[cm/ns]
Definition Const.h:695
Replacement for TDatabasePDG that is filled from EvtGen's evt.pdl.
static EvtGenDatabasePDG * Instance()
Instance method that loads the EvtGen table.
void getDisplacement(const MCParticle &particle, float lifetime, ROOT::Math::PxPyPzEVector &displacement)
Helper function to calculate the numerical value of the vertex displacement (x,y,z,...
virtual void initialize() override
Register input and output data, initialises the module.
virtual void event() override
Method is called for each event.
StoreArray< MCParticle > m_mcparticles
store array for the MCParticles
float m_maxDecayTime
Set the maximal decayTime for the options 'flat' and 'exponential'.
void displaceDaughter(ROOT::Math::PxPyPzEVector &motherDisplacementVector, std::vector< MCParticle * > daughters)
Helper function to loop over subsequent daughters and displaces their vertices corresponding to their...
virtual void terminate() override
Terminates the module.
GeneratedVertexDisplacerModule()
Constructor: Sets the description, the properties and the parameters of the module.
void displace(MCParticle &particle, float lifetime)
Helper function to displace the mother particles (corresponding to given pdf values).
std::string m_lifetimeOption
Set the lifetime option, either fixed, flat exponential.
std::vector< int > m_pdgVals
Set the particles whose vertices should be displaced.
std::string m_particleList
The name of the MCParticle collection.
std::vector< float > m_lifetime
Set the numerical value of the lifetime ctau [cm].
A Class to store the Monte Carlo particle information.
Definition MCParticle.h:32
@ c_Initial
bit 5: Particle is initial such as e+ or e- and not going to Geant4
Definition MCParticle.h:57
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition MCParticle.h:47
ROOT::Math::XYZVector getDecayVertex() const
Return decay vertex.
Definition MCParticle.h:208
std::vector< Belle2::MCParticle * > getDaughters() const
Get vector of all daughter particles, empty vector if none.
Definition MCParticle.cc:52
bool hasStatus(unsigned short int bitmask) const
Return if specific status bit is set.
Definition MCParticle.h:118
int getArrayIndex() const
Get 0-based index of the particle in the corresponding MCParticle list.
Definition MCParticle.h:233
ROOT::Math::XYZVector getProductionVertex() const
Return production vertex position.
Definition MCParticle.h:178
void setValidVertex(bool valid)
Set indication whether vertex and time information is valid or just default.
Definition MCParticle.h:367
void setProductionVertex(const ROOT::Math::XYZVector &vertex)
Set production vertex position.
Definition MCParticle.h:385
int getNDaughters() const
Return number of daughter MCParticles.
Definition MCParticle.cc:75
int getPDG() const
Return PDG code of particle.
Definition MCParticle.h:101
float getProductionTime() const
Return production time in ns.
Definition MCParticle.h:148
void setProductionTime(float time)
Set production time.
Definition MCParticle.h:373
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.
STL namespace.