Belle II Software  release-06-01-15
KlongDecayReconstructorExpertModule.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/KlongDecayReconstructorExpertModule.h>
11 
12 // framework aux
13 #include <framework/logging/Logger.h>
14 
15 // decay descriptor
16 #include <analysis/DecayDescriptor/DecayDescriptorParticle.h>
17 
18 // utilities
19 #include <analysis/DecayDescriptor/ParticleListName.h>
20 
21 #include <memory>
22 
23 using namespace std;
24 
25 namespace Belle2 {
31 //-----------------------------------------------------------------
32 // Register module
33 //-----------------------------------------------------------------
34 
35  REG_MODULE(KlongDecayReconstructorExpert)
36 
37 //-----------------------------------------------------------------
38 // Implementation
39 //-----------------------------------------------------------------
40 
42  Module(), m_pdgCode(0), m_isSelfConjugatedParticle(false)
43 
44  {
45  // set module description (e.g. insert text)
46  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 initial state.");
47  setPropertyFlags(c_ParallelProcessingCertified);
48 
49  // Add parameters
50  addParam("decayString", m_decayString,
51  "Input DecayDescriptor string.");
52  addParam("cut", m_cutParameter, "Selection criteria to be applied", std::string(""));
53  addParam("maximumNumberOfCandidates", m_maximumNumberOfCandidates,
54  "Don't reconstruct channel if more candidates than given are produced.", -1);
55  addParam("decayMode", m_decayModeID, "User-specified decay mode identifier (saved in 'decayModeID' extra-info for each Particle)",
56  0);
57  addParam("writeOut", m_writeOut,
58  "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.", false);
59  addParam("recoList", m_recoList,
60  "Suffix attached to the original K_L input list to identify the output list of the FindKlongMomentum module; this is the input for this module, if not defined it is set to '_reco' \n",
61  std::string("_reco"));
62 
63  }
64 
65  void KlongDecayReconstructorExpertModule::initialize()
66  {
67  m_particles.isRequired();
68 
69  // clear everything, initialize private members
70  m_listName = "";
71  m_generator = nullptr;
72 
73  // obtain the input and output particle lists from the decay string
74  bool valid = m_decaydescriptor.init(m_decayString);
75  if (!valid)
76  B2ERROR("Invalid input DecayString: " << m_decayString);
77 
78  // Mother particle
79  const DecayDescriptorParticle* mother = m_decaydescriptor.getMother();
80 
81  m_pdgCode = mother->getPDGCode();
82  m_listName = mother->getFullName();
83 
84  m_antiListName = ParticleListName::antiParticleListName(m_listName);
85  m_isSelfConjugatedParticle = (m_listName == m_antiListName);
86 
87  std::string newDecayString;
88  std::string kListName;
89  newDecayString = m_listName + " -> ";
90 
91  bool k_check = false;
92 
93  // Daughters
94  int nProducts = m_decaydescriptor.getNDaughters();
95  for (int i = 0; i < nProducts; ++i) {
96  const DecayDescriptorParticle* daughter = m_decaydescriptor.getDaughter(i)->getMother();
97  if (daughter->getPDGCode() != Const::Klong.getPDGCode()) {
98  StoreObjPtr<ParticleList>().isRequired(daughter->getFullName());
99  newDecayString = newDecayString + daughter->getFullName() + " ";
100  } else {
101  StoreObjPtr<ParticleList>().isRequired(daughter->getFullName() + m_recoList);
102  kListName = daughter->getFullName() + m_recoList;
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  newDecayString = newDecayString + kListName;
110 
111  m_generator = std::make_unique<ParticleGenerator>(newDecayString, m_cutParameter);
112 
113  DataStore::EStoreFlags flags = m_writeOut ? DataStore::c_WriteOut : DataStore::c_DontWriteOut;
114  m_outputList.registerInDataStore(m_listName, flags);
115  if (!m_isSelfConjugatedParticle) {
116  m_outputAntiList.registerInDataStore(m_antiListName, flags);
117  }
118 
119  m_cut = Variable::Cut::compile(m_cutParameter);
120 
121  }
122 
123  void KlongDecayReconstructorExpertModule::event()
124  {
125  m_outputList.create();
126  m_outputList->initialize(m_pdgCode, m_listName);
127 
128  if (!m_isSelfConjugatedParticle) {
129  m_outputAntiList.create();
130  m_outputAntiList->initialize(-1 * m_pdgCode, m_antiListName);
131 
132  m_outputList->bindAntiParticleList(*(m_outputAntiList));
133  }
134 
135  m_generator->init();
136 
137  int numberOfCandidates = 0;
138  while (m_generator->loadNext()) {
139 
140  Particle particle = m_generator->getCurrentParticle();
141 
142  bool is_physical = true;
143 
144  const std::vector<Particle*> daughters = particle.getDaughters();
145 
146  if (daughters.size() < 2)
147  B2FATAL("Reconstructing particle as a daughter of a decay with less than 2 daughters!");
148 
149  if (daughters.size() > 3)
150  B2FATAL("Higher multiplicity (>2) missing momentum decays not implemented yet!");
151 
152  int e_check = 0;
153  TLorentzVector pDaughters;
154  for (auto daughter : daughters) {
155  if (daughter->getPDGCode() != Const::Klong.getPDGCode()) {
156  pDaughters += daughter->get4Vector();
157  e_check = daughter->getArrayIndex() + e_check * 100;
158  }
159  }
160 
161 
162  TLorentzVector klDaughters;
163  for (auto daughter : daughters) {
164  if (daughter->getPDGCode() == Const::Klong.getPDGCode()) {
165  klDaughters += daughter->get4Vector();
166  if (e_check != daughter->getExtraInfo("permID")) {
167  is_physical = false;
168  }
169  }
170  }
171  double m_b = particle.getPDGMass();
172 
173  TLorentzVector mom = pDaughters + klDaughters;
174  mom.SetE(TMath::Sqrt(mom.Vect().Mag2() + m_b * m_b));
175  if ((!isnan(mom.Vect().Mag())) && is_physical)
176  particle.set4Vector(mom);
177  if (isnan(mom.Vect().Mag()))
178  is_physical = false;
179 
180  if (!m_cut->check(&particle))
181  continue;
182 
183  if (!is_physical)
184  continue;
185 
186  numberOfCandidates++;
187 
188  if (m_maximumNumberOfCandidates > 0 and numberOfCandidates > m_maximumNumberOfCandidates) {
189  m_outputList->clear();
190  break;
191  }
192 
193  Particle* newParticle = m_particles.appendNew(particle);
194 
195  m_outputList->addParticle(newParticle);
196  newParticle->addExtraInfo("decayModeID", m_decayModeID);
197 
198  } //while
199 
200  } //event
201 
203 } // end Belle2 namespace
204 
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 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.
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.