Belle II Software  light-2205-abys
NeutralHadron4MomentumCalculatorModule.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 <analysis/modules/NeutralHadron4MomentumCalculator/NeutralHadron4MomentumCalculatorModule.h>
10 
11 #include <framework/logging/Logger.h>
12 #include <analysis/dataobjects/Particle.h>
13 #include <analysis/DecayDescriptor/DecayDescriptorParticle.h>
14 #include <mdst/dataobjects/KLMCluster.h>
15 #include <analysis/utility/ParticleCopy.h>
16 #include <framework/geometry/B2Vector3.h>
17 #include <Math/Vector4D.h>
18 #include <vector>
19 #include <cmath>
20 
21 using namespace Belle2;
22 
23 REG_MODULE(NeutralHadron4MomentumCalculator);
24 
26 {
27  // Set module properties
29  R"DOC(Calculates 4-momentum of a neutral hadron in a given decay chain e.g. B0 -> J/Psi K_L0, or anti-B0 -> p+ K- anti-n0.)DOC");
30 
31  // Parameter definitions
32  addParam("decayString", m_decayString, "Decay string for which one wants to perform the calculation", std::string(""));
33  addParam("allowGamma", m_allowGamma, "Whether allow the selected particle to be gamma", false);
34 
35 }
36 
38 {
39  B2DEBUG(17, "Neutralhadron4MomentumCalculator: Use particle list: " << m_decayString);
40  bool valid = m_decayDescriptor.init(m_decayString);
41  if (!valid)
42  B2ERROR("NeutralHadron4MomentumCalculatorModule::initialize Invalid Decay Descriptor " << m_decayString);
43 
44  auto hierarchy = m_decayDescriptor.getHierarchyOfSelected();
45  if (hierarchy.size() != 1)
46  B2ERROR("NeutralHadron4MomentumCalculatorModule::initialize Only one particle can be selected in " << m_decayString);
47  if (hierarchy[0].size() != 2)
48  B2ERROR("NeutralHadron4MomentumCalculatorModule::initialize The selected particle must be a direct daughter " << m_decayString);
49 
50  std::string neutralHadronName = hierarchy[0][1].second;
51  if (neutralHadronName != "n0" and neutralHadronName != "K_L0") {
52  if (m_allowGamma == true and hierarchy[0][1].second == "gamma")
53  B2WARNING("NeutralHadron4MomentumCalculatorModule::initialize The selected particle is gamma but you allowed so; be aware.");
54  else
55  B2ERROR("NeutralHadron4MomentumCalculatorModule::initialize The selected particle must be a long-lived neutral hadron "
56  "i.e. (anti-)n0 or K_L0, or at least a photon (gamma), in which case you need to set allowGamma as true."
57  "Input particle: " << m_decayString);
58  }
59 
60  m_iNeutral = hierarchy[0][1].first;
61 
62  std::string motherFullName = m_decayDescriptor.getMother()->getFullName();
63  m_plist.isRequired(motherFullName);
64 }
65 
67 {
68  const unsigned int n = m_plist->getListSize();
69  std::vector<unsigned int> toRemove;
70  for (unsigned i = 0; i < n; i++) {
71  Particle* particle = m_plist->getParticle(i);
72  std::vector<Particle*> daughters = particle->getDaughters();
73  ROOT::Math::PxPyPzEVector others4Momentum;
74  for (int j = 0; j < m_decayDescriptor.getNDaughters(); j++) {
75  if (j != m_iNeutral) {
76  others4Momentum += daughters[j]->get4Vector();
77  }
78  }
79  const Particle* originalNeutral = daughters[m_iNeutral];
80  Particle* neutral = ParticleCopy::copyParticle(originalNeutral);
81  particle->removeDaughter(originalNeutral);
82  particle->appendDaughter(neutral);
83  B2Vector3D neutralDirection;
84  if (neutral->getParticleSource() == Particle::EParticleSourceObject::c_ECLCluster) {
85  neutralDirection = neutral->getECLCluster()->getClusterPosition().Unit();
86  } else if (neutral->getParticleSource() == Particle::EParticleSourceObject::c_KLMCluster) {
87  neutralDirection = neutral->getKLMCluster()->getClusterPosition().Unit();
88  } else {
89  B2ERROR("Your neutral particle doesn't originate from ECLCluster nor KLMCluster.");
90  }
91  double a = others4Momentum.Vect().Dot(neutralDirection);
92  double b = (std::pow(particle->getPDGMass(), 2) - std::pow(neutral->getMass(), 2) - others4Momentum.mag2()) / 2.;
93  double c = others4Momentum.E();
94  double d = std::pow(neutral->getMass(), 2);
95  double D = (a * a - c * c) * d + b * b;
96  if (D >= 0) {
97  double neutralP = (-1. * a * b - c * std::sqrt(D)) / (a * a - c * c);
98  double neutralPx = neutralP * neutralDirection.x();
99  double neutralPy = neutralP * neutralDirection.y();
100  double neutralPz = neutralP * neutralDirection.z();
101  double neutralE = std::sqrt(neutralP * neutralP + d);
102  const ROOT::Math::PxPyPzEVector newNeutral4Momentum(neutralPx, neutralPy, neutralPz, neutralE);
103 
104  double motherPx = newNeutral4Momentum.Px() + others4Momentum.Px();
105  double motherPy = newNeutral4Momentum.Py() + others4Momentum.Py();
106  double motherPz = newNeutral4Momentum.Pz() + others4Momentum.Pz();
107  double motherE = newNeutral4Momentum.E() + others4Momentum.E();
108  const ROOT::Math::PxPyPzEVector newMother4Momentum(motherPx, motherPy, motherPz, motherE);
109 
110  neutral->set4Vector(newNeutral4Momentum);
111  particle->set4Vector(newMother4Momentum);
112  } else {
113  toRemove.push_back(particle->getArrayIndex());
114  }
115  }
116  m_plist->removeParticles(toRemove);
117 }
DataType y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:421
DataType z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:423
DataType x() const
access variable X (= .at(0) without boundary check)
Definition: B2Vector3.h:419
std::string getFullName() const
returns the full name of the particle full_name = name:label
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
const DecayDescriptorParticle * getMother() const
return mother.
int getNDaughters() const
return number of direct daughters.
std::vector< std::vector< std::pair< int, std::string > > > getHierarchyOfSelected()
Function to get hierarchy of selected particles and their names (for python use)
TVector3 getClusterPosition() const
Return TVector3 on cluster position (x,y,z)
Definition: ECLCluster.cc:40
TVector3 getClusterPosition() const
Get global position (TVector3 version).
Definition: KLMCluster.h:80
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void event() override
Action to perform for each event.
std::string m_decayString
Decay string for which one wants to perform the calculation.
int m_iNeutral
Index of the neutral hadron in the decay string.
NeutralHadron4MomentumCalculatorModule()
Constructor: Sets the description, the properties and the parameters of the module.
DecayDescriptor m_decayDescriptor
Decay Descriptor to be initialized with m_decayString.
bool m_allowGamma
Whether allow the selected particle to be gamma.
StoreObjPtr< ParticleList > m_plist
ParticleList that one wants to perform the calculation.
Class to store reconstructed particles.
Definition: Particle.h:74
const KLMCluster * getKLMCluster() const
Returns the pointer to the KLMCluster object that was used to create this Particle (ParticleType == c...
Definition: Particle.cc:918
const ECLCluster * getECLCluster() const
Returns the pointer to the ECLCluster object that was used to create this Particle (if ParticleType =...
Definition: Particle.cc:883
std::vector< Belle2::Particle * > getDaughters() const
Returns a vector of pointers to daughter particles.
Definition: Particle.cc:660
double getPDGMass(void) const
Returns uncertainty on the invariant mass (requires valid momentum error matrix)
Definition: Particle.cc:636
void set4Vector(const ROOT::Math::PxPyPzEVector &p4)
Sets Lorentz vector.
Definition: Particle.h:276
EParticleSourceObject getParticleSource() const
Returns particle source as defined with enum EParticleSourceObject.
Definition: Particle.h:427
void removeDaughter(const Particle *daughter, const bool updateType=true)
Removes index of daughter from daughters index array.
Definition: Particle.cc:712
void appendDaughter(const Particle *daughter, const bool updateType=true)
Appends index of daughter to daughters index array.
Definition: Particle.cc:700
double getMass() const
Returns invariant mass (= nominal for FS particles)
Definition: Particle.h:456
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
REG_MODULE(B2BIIConvertBeamParams)
Register the module.
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:560
Particle * copyParticle(const Particle *original)
Function takes argument Particle and creates a copy of it and copies of all its (grand-)^n-daughters.
Definition: ParticleCopy.cc:18
Abstract base class for different kinds of events.
Definition: ClusterUtils.h:23