Belle II Software  release-06-02-00
KlongMomentumCalculatorExpertModule.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 // Own include
10 #include <analysis/modules/KlongDecayReconstructor/KlongMomentumCalculatorExpertModule.h>
11 
12 // framework aux
13 #include <framework/logging/Logger.h>
14 
15 // dataobjects
16 #include <analysis/dataobjects/Particle.h>
17 
18 // decay descriptor
19 #include <analysis/DecayDescriptor/DecayDescriptorParticle.h>
20 
21 // utilities
22 #include <analysis/DecayDescriptor/ParticleListName.h>
23 #include <analysis/utility/ParticleCopy.h>
24 
25 #include <memory>
26 
27 using namespace std;
28 
29 namespace Belle2 {
35 //-----------------------------------------------------------------
36 // Register module
37 //-----------------------------------------------------------------
38 
39  REG_MODULE(KlongMomentumCalculatorExpert)
40 
41 //-----------------------------------------------------------------
42 // Implementation
43 //-----------------------------------------------------------------
44 
46  Module(), m_pdgCode(0)
47 
48  {
49  // set module description (e.g. insert text)
50  setDescription("This module is used to employ kinematic constraints to determine the momentum of Klongs for two body B decays containing a K_L0 and something else. The module creates a list of K_L0 candidates whose K_L0 momentum is reconstructed by combining the reconstructed direction (from either the ECL or KLM) of the K_L0 and kinematic constraints of the intial state.");
51  setPropertyFlags(c_ParallelProcessingCertified);
52 
53  // Add parameters
54  addParam("decayString", m_decayString,
55  "Input DecayDescriptor string.");
56  addParam("cut", m_cutParameter, "Selection criteria to be applied", std::string(""));
57  addParam("maximumNumberOfCandidates", m_maximumNumberOfCandidates,
58  "Don't reconstruct channel if more candidates than given are produced.", -1);
59  addParam("decayMode", m_decayModeID, "User-specified decay mode identifier (saved in 'decayModeID' extra-info for each Particle)",
60  0);
61  addParam("writeOut", m_writeOut,
62  "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.", false);
63  addParam("recoList", m_recoList,
64  "Suffix attached to the output K_L list, if not defined it is set to '_reco' \n", std::string("_reco"));
65 
66  }
67 
68  void KlongMomentumCalculatorExpertModule::initialize()
69  {
71 
72  // clear everything, initialize private members
73  m_pdgCode = 0;
74  m_listName = "";
75  m_isSelfConjugatedParticle = false;
76  m_generator = nullptr;
77 
78  // obtain the input and output particle lists from the decay string
79  bool valid = m_decaydescriptor.init(m_decayString);
80  if (!valid)
81  B2ERROR("Invalid input DecayString: " << m_decayString);
82 
83  // Mother particle
84  const DecayDescriptorParticle* mother = m_decaydescriptor.getMother();
85 
86  m_pdgCode = mother->getPDGCode();
87  m_listName = mother->getFullName();
88 
89  m_antiListName = ParticleListName::antiParticleListName(m_listName);
90  m_isSelfConjugatedParticle = (m_listName == m_antiListName);
91 
92  m_klistName = m_recoList;
93 
94  // Daughters
95  bool k_check = false;
96  int nProducts = m_decaydescriptor.getNDaughters();
97  for (int i = 0; i < nProducts; ++i) {
98  const DecayDescriptorParticle* daughter =
99  m_decaydescriptor.getDaughter(i)->getMother();
100  StoreObjPtr<ParticleList>().isRequired(daughter->getFullName());
101  if (daughter->getPDGCode() == Const::Klong.getPDGCode()) {
102  m_klistName = daughter->getFullName() + m_klistName;
103  k_check = true;
104  }
105  }
106 
107  if (!k_check)
108  B2FATAL("This module is meant to reconstruct decays with a K_L0 in the final state. There is no K_L0 in this decay!");
109 
110  m_generator = std::make_unique<ParticleGenerator>(m_decayString, m_cutParameter);
111 
112  DataStore::EStoreFlags flags = m_writeOut ? DataStore::c_WriteOut : DataStore::c_DontWriteOut;
113  m_koutputList.registerInDataStore(m_klistName, flags);
114 
115  m_cut = Variable::Cut::compile(m_cutParameter);
116 
117  }
118 
119  void KlongMomentumCalculatorExpertModule::event()
120  {
121  m_koutputList.create();
122  m_koutputList->initialize(Const::Klong.getPDGCode(), m_klistName);
123 
124  m_generator->init();
125 
126  int numberOfCandidates = 0;
127  while (m_generator->loadNext()) {
128 
129  Particle particle = m_generator->getCurrentParticle();
130 
131  TLorentzVector missDaughters;
132  Particle* kparticle = nullptr;
133 
134  bool is_physical = true;
135 
136  const std::vector<Particle*> daughters = particle.getDaughters();
137 
138  if (daughters.size() < 2)
139  B2FATAL("Reconstructing particle as a daughter of a decay with less then 2 daughters!");
140 
141  if (daughters.size() > 3)
142  B2FATAL("Higher multiplicity (>2) missing momentum decays not implemented yet!");
143 
144  TLorentzVector pDaughters;
145  for (auto daughter : daughters) {
146  if (daughter->getPDGCode() != Const::Klong.getPDGCode()) {
147  pDaughters += daughter->get4Vector();
148  }
149  }
150 
151  TLorentzVector klDaughters;
152  for (auto daughter : daughters) {
153  if (daughter->getPDGCode() == Const::Klong.getPDGCode()) {
154  kparticle = ParticleCopy::copyParticle(daughter);
155  klDaughters += daughter->get4Vector();
156  }
157  }
158 
159  double k_mag1 = 0.;
160  double k_mag2 = 0.;
161  double m_b = particle.getPDGMass();
162  double m_k = Const::Klong.getMass();
163  double m_j = 0;
164 
165  int idx = 0;
166 
167  for (auto daughter : daughters) {
168  if (daughter->getPDGCode() != Const::Klong.getPDGCode()) {
169  m_j = daughter->getPDGMass();
170  idx = daughter->getArrayIndex() + idx * 100;
171  }
172  }
173 
174  if (daughters.size() == 3) {
175  m_j = pDaughters.M();
176  }
177 
178  double s_p = (klDaughters.Vect().Unit()).Dot(pDaughters.Vect());
179  double m_sum = (m_b * m_b) - (m_j * m_j) - (m_k * m_k);
180  double e_j = pDaughters.E();
181 
182  double s_p2 = s_p * s_p;
183  double m_sum2 = m_sum * m_sum;
184  double s_pm = s_p * m_sum;
185  double e_j2 = e_j * e_j;
186  double m_k2 = m_k * m_k;
187 
188  k_mag1 = (s_pm + std::sqrt((s_p2) * (m_sum2) - 4 * ((e_j2) - (s_p2)) * ((e_j2) * (m_k2) - (m_sum2) / 4))) / (2 * (e_j2 - s_p2));
189  k_mag2 = (s_pm - std::sqrt((s_p2) * (m_sum2) - 4 * ((e_j2) - (s_p2)) * ((e_j2) * (m_k2) - (m_sum2) / 4))) / (2 * (e_j2 - s_p2));
190 
191  if (k_mag1 > 0)
192  missDaughters.SetVect(k_mag1 * (klDaughters.Vect().Unit()));
193  else
194  missDaughters.SetVect(k_mag2 * (klDaughters.Vect().Unit()));
195  missDaughters.SetE(std::sqrt(m_k * m_k + missDaughters.Vect().Mag2()));
196 
197  for (auto daughter : daughters) {
198  if (daughter->getPDGCode() == Const::Klong.getPDGCode()) {
199  if (!isnan(missDaughters.Vect().Mag())) {
200  kparticle->set4Vector(missDaughters);
201  } else
202  is_physical = false;
203  }
204  }
205 
206  if (is_physical) {
207  TLorentzVector mom = pDaughters + missDaughters;
208  mom.SetE(std::sqrt(m_b * m_b + mom.Vect().Mag2()));
209  particle.set4Vector(mom);
210  if (isnan(mom.Vect().Mag()))
211  is_physical = false;
212  }
213 
214  if (!m_cut->check(&particle))
215  continue;
216 
217  if (!is_physical)
218  continue;
219 
220  numberOfCandidates++;
221 
222  if (m_maximumNumberOfCandidates > 0 and numberOfCandidates > m_maximumNumberOfCandidates) {
223  m_koutputList->clear();
224  break;
225  }
226 
227  m_koutputList->addParticle(kparticle);
228  kparticle->addExtraInfo("permID", idx);
229 
230  } //while
231 
232  } //event
233 
235 } // end Belle2 namespace
236 
EStoreFlags
Flags describing behaviours of objects etc.
Definition: DataStore.h:69
Represents a particle in the DecayDescriptor.
Base class for Modules.
Definition: Module.h:72
Class to store reconstructed particles.
Definition: Particle.h:74
void set4Vector(const TLorentzVector &p4)
Sets Lorentz vector.
Definition: Particle.h:276
void addExtraInfo(const std::string &name, float value)
Sets the user-defined data of given name to the given value.
Definition: Particle.cc:1289
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.