Belle II Software  release-06-02-00
InclusiveDstarReconstructionModule.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/InclusiveDstarReconstruction/InclusiveDstarReconstructionModule.h>
10 #include <analysis/utility/PCmsLabTransform.h>
11 
12 #include <analysis/DecayDescriptor/ParticleListName.h>
13 
14 #include <framework/gearbox/Const.h>
15 
16 #include <TVector3.h>
17 #include <TDatabasePDG.h>
18 
19 using namespace Belle2;
20 
21 //-----------------------------------------------------------------
22 // Register the Module
23 //-----------------------------------------------------------------
24 REG_MODULE(InclusiveDstarReconstruction)
25 
26 //-----------------------------------------------------------------
27 // Implementation
28 //-----------------------------------------------------------------
30 {
31  // Set module properties
32  setDescription("Inclusive Dstar reconstruction by estimating the four vector using slow pions");
33 
34  // Parameter definitions
35  addParam("decayString", m_decayString, "Input DecayDescriptor string", std::string(""));
36  addParam("slowPionCut", m_slowPionCut, "Cut for slow pions", std::string("useCMSFrame(p) < 0.2"));
37  addParam("DstarCut", m_DstarCut, "Cut for Dstar", std::string(""));
38 
39  m_dstar_pdg_code = 0;
40  m_dstar_pdg_mass = 0;
41  m_d_pdg_mass = 0;
42 }
43 
45 
47 {
48  m_outputListName = "";
50  m_pionListName = "";
51 
52  bool valid = m_decaydescriptor.init(m_decayString);
53  if (!valid)
54  B2ERROR("Invalid input DecayString: " << m_decayString);
55 
56  // mother particle: D*
58  m_dstar_pdg_code = mother->getPDGCode();
59 
60  // daughter particle: pion (is the only daughter)
61  int pion_pdg_code = 0;
63  m_pionListName = daughter->getFullName();
64  m_inputPionList.isRequired(m_pionListName);
65  pion_pdg_code = daughter->getPDGCode();
66 
67  if (!pionCompatibleWithDstar(pion_pdg_code))
68  B2ERROR("Pion PDG code " << pion_pdg_code << " not compatible with D* PDG code " << m_dstar_pdg_code);
69 
70  // create and register output particle list
71  m_outputListName = mother->getFullName();
72  m_outputDstarList.registerInDataStore(m_outputListName);
73  // create and register output antiparticle list
75  m_outputAntiDstarList.registerInDataStore(m_outputAntiListName);
76 
79 
80  m_dstar_pdg_mass = TDatabasePDG::Instance()->GetParticle(m_dstar_pdg_code)->Mass();
81 
82  // get the mass of daughter-D:
83  /*
84  decay 1. D*+ {413} -> pi+ {211} D0 {421}
85  decay 2. D*+ {413} -> pi0 {111} D+ {411}
86  decay 3. D*0 {423} -> pi0 {111} D0 {421}
87  */
88  int d_pdg_code = 0;
89  if (abs(m_dstar_pdg_code) == 413) {
90  d_pdg_code = (pion_pdg_code == Const::pi0.getPDGCode()) ? 411 : 421;
91  } else {
92  d_pdg_code = 421;
93  }
94  m_d_pdg_mass = TDatabasePDG::Instance()->GetParticle(d_pdg_code)->Mass();
95 }
96 
98 {
99 
100  m_outputDstarList.create();
101  m_outputDstarList->initialize(m_dstar_pdg_code, m_outputDstarList.getName());
102 
103  m_outputAntiDstarList.create();
105  m_outputDstarList->bindAntiParticleList(*m_outputAntiDstarList);
106 
107  unsigned int num_pions = m_inputPionList->getListSize();
108 
109  for (unsigned int pion_index = 0; pion_index < num_pions; pion_index++) {
110  const Particle* pion = m_inputPionList->getParticle(pion_index);
111 
112  if (!m_cut_pion->check(pion)) continue;
113 
114  TLorentzVector dstar_four_vector = estimateDstarFourMomentum(pion);
115 
116  if (isnan(dstar_four_vector.P())) continue;
117 
118  /*
119  decay 1:
120  - pion-charge > 0: m_dstar_pdg_code
121  - pion-charge < 0: -m_dstar_pdg_code
122  decay 2 and 3:
123  - pion-charge = 0: m_dstar_pdg_code as well as -m_dstar_pdg_code
124  - for these cases we need to store the particleList and antiParticleList
125  with the same candidates
126  */
127 
128  int particle_properties = Particle::PropertyFlags::c_IsIgnoreRadiatedPhotons
129  + Particle::PropertyFlags::c_IsIgnoreIntermediate
130  + Particle::PropertyFlags::c_IsIgnoreMassive
131  + Particle::PropertyFlags::c_IsIgnoreNeutrino
132  + Particle::PropertyFlags::c_IsIgnoreGamma;
133 
134  // for decay 1 and decay 2/3 with positive flavor
135  int output_dstar_pdg = getDstarOutputPDG(pion->getCharge(), m_dstar_pdg_code);
136  Particle dstar = Particle(dstar_four_vector, output_dstar_pdg,
137  Particle::EFlavorType::c_Flavored, {pion->getArrayIndex()},
138  particle_properties, pion->getArrayPointer());
139 
140  Particle* new_dstar = m_particles.appendNew(dstar);
141  if (!m_cut_dstar->check(new_dstar)) continue;
142  m_outputDstarList->addParticle(new_dstar);
143 
144  // for decay 2/3 with negative flavor
145  if (pion->getCharge() == 0) {
146  Particle antidstar = Particle(dstar_four_vector, -m_dstar_pdg_code,
147  Particle::EFlavorType::c_Flavored, {pion->getArrayIndex()},
148  particle_properties, pion->getArrayPointer());
149 
150  Particle* new_antidstar = m_particles.appendNew(antidstar);
151  if (!m_cut_dstar->check(new_antidstar)) continue;
152  m_outputAntiDstarList->addParticle(new_antidstar);
153  }
154  }
155 }
156 
158 {
159  // estimate D* energy and absolute momentum using the slow pion energy
160  double energy_dstar = pion->getEnergy() * m_dstar_pdg_mass / (m_dstar_pdg_mass - m_d_pdg_mass);
161  double abs_momentum_dstar = sqrt(energy_dstar * energy_dstar - m_dstar_pdg_mass * m_dstar_pdg_mass);
162 
163  // dstar momentum approximated collinear to pion direction
164  TVector3 momentum_vector_pion = pion->getMomentum();
165  TVector3 momentum_vec_dstar = abs_momentum_dstar * momentum_vector_pion.Unit();
166 
167  return TLorentzVector(momentum_vec_dstar, energy_dstar);
168 }
169 
171 {
172  bool is_compatible = false;
173  if (pion_pdg_code == Const::pi0.getPDGCode()) {
174  is_compatible = true;
175  } else if (pion_pdg_code == Const::pion.getPDGCode()) {
176  is_compatible = (m_dstar_pdg_code == 413);
177  } else if (pion_pdg_code == -Const::pion.getPDGCode()) {
178  is_compatible = (m_dstar_pdg_code == -413);
179  }
180  return is_compatible;
181 }
182 
183 int InclusiveDstarReconstructionModule::getDstarOutputPDG(int pion_charge, int input_dstar_pdg)
184 {
185  // Helper function to get the correct D* PDG code depending on the input (DecayDescriptor)
186  // and the charge of the reconstructed pion
187 
188  // DecayDescriptor: D*+ -> pi0 or D*0 -> pi0
189  // the opposite (D*- -> pi0 or anti-D*0 -> pi0) are treated from line 150.
190  if (pion_charge == 0) {
191  return input_dstar_pdg;
192  }
193 
194  else {
195  // DecayDescriptor: D*+ -> pi+
196  if (input_dstar_pdg > 0) {
197  return (pion_charge > 0) ? input_dstar_pdg : -input_dstar_pdg;
198  }
199  // DecayDescriptor: D* -> pi-
200  else {
201  return (pion_charge < 0) ? input_dstar_pdg : -input_dstar_pdg;
202  }
203  }
204 
205 }
int getPDGCode() const
PDG code.
Definition: Const.h:354
static const ParticleType pi0
neutral pion particle
Definition: Const.h:555
static const ChargedStable pion
charged pion particle
Definition: Const.h:542
Represents a particle in the DecayDescriptor.
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
const DecayDescriptorParticle * getMother() const
return mother.
const DecayDescriptor * getDaughter(int i) const
return i-th daughter (0 based index).
static std::unique_ptr< GeneralCut > compile(const std::string &cut)
Creates an instance of a cut and returns a unique_ptr to it, if you need a copy-able object instead y...
Definition: GeneralCut.h:104
std::unique_ptr< Variable::Cut > m_cut_dstar
cut object which performs the cuts
bool pionCompatibleWithDstar(int pion_pdg_code)
Checks if the given pion is list if compatible with the charge of the D* particle.
virtual void initialize() override
Initialize the Module.
int m_dstar_pdg_code
PDG code of the given D* particle list.
StoreObjPtr< ParticleList > m_inputPionList
input pion particle list
std::string m_decayString
Input DecayDescriptor string.
StoreArray< Particle > m_particles
StoreArray of Particles.
virtual ~InclusiveDstarReconstructionModule()
Destructor.
StoreObjPtr< ParticleList > m_outputDstarList
output Dstar particle list
StoreObjPtr< ParticleList > m_outputAntiDstarList
output anti-Dstar particle list
DecayDescriptor m_decaydescriptor
Decay descriptor for parsing the user specified DecayString.
int getDstarOutputPDG(int pion_charge, int input_dstar_pdg)
Helper function to get the correct D* PDG code for the output list, depending on the input (DecayStri...
TLorentzVector estimateDstarFourMomentum(const Particle *pion)
Estimates the D* four momentum given a slow pion.
std::string m_pionListName
Name of the input pion particle list.
std::unique_ptr< Variable::Cut > m_cut_pion
cut object which performs the cuts
std::string m_outputAntiListName
Name of the output anti-D* particle list.
std::string m_outputListName
Name of the output D* particle list.
Base class for Modules.
Definition: Module.h:72
Class to store reconstructed particles.
Definition: Particle.h:74
float getEnergy() const
Returns total energy.
Definition: Particle.h:467
TClonesArray * getArrayPointer() const
Returns the pointer to the store array which holds the daughter particles.
Definition: Particle.h:866
TVector3 getMomentum() const
Returns momentum vector.
Definition: Particle.h:488
float getCharge(void) const
Returns particle charge.
Definition: Particle.cc:630
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
std::string antiParticleListName(const std::string &listName)
Returns name of anti-particle-list corresponding to listName.
Abstract base class for different kinds of events.