Belle II Software  release-08-01-10
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 header.
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 <Math/Vector4D.h>
22 #include <TMath.h>
23 
24 #include <memory>
25 
26 using namespace std;
27 using namespace Belle2;
28 
29 //-----------------------------------------------------------------
30 // Register module
31 //-----------------------------------------------------------------
32 
33 REG_MODULE(KlongDecayReconstructorExpert);
34 
35 //-----------------------------------------------------------------
36 // Implementation
37 //-----------------------------------------------------------------
38 
39 KlongDecayReconstructorExpertModule::KlongDecayReconstructorExpertModule() :
40  Module(), m_pdgCode(0), m_isSelfConjugatedParticle(false)
41 
42 {
43  // set module description (e.g. insert text)
44  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.");
46 
47  // Add parameters
48  addParam("decayString", m_decayString,
49  "Input DecayDescriptor string.");
50  addParam("cut", m_cutParameter, "Selection criteria to be applied", std::string(""));
51  addParam("maximumNumberOfCandidates", m_maximumNumberOfCandidates,
52  "Don't reconstruct channel if more candidates than given are produced.", -1);
53  addParam("decayMode", m_decayModeID, "User-specified decay mode identifier (saved in 'decayModeID' extra-info for each Particle)",
54  0);
55  addParam("writeOut", m_writeOut,
56  "If true, the output ParticleList will be saved by RootOutput. If false, it will be ignored when writing the file.", false);
57  addParam("recoList", m_recoList,
58  "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",
59  std::string("_reco"));
60 
61 }
62 
64 {
65  m_particles.isRequired();
66 
67  // clear everything, initialize private members
68  m_listName = "";
69  m_generator = nullptr;
70 
71  // obtain the input and output particle lists from the decay string
72  bool valid = m_decaydescriptor.init(m_decayString);
73  if (!valid)
74  B2ERROR("Invalid input DecayString: " << m_decayString);
75 
76  // Mother particle
78 
79  m_pdgCode = mother->getPDGCode();
80  m_listName = mother->getFullName();
81 
84 
85  std::string newDecayString;
86  std::string kListName;
87  newDecayString = m_listName + " -> ";
88 
89  // Daughters
90  bool k_check = false;
91  int nProducts = m_decaydescriptor.getNDaughters();
92  for (int i = 0; i < nProducts; ++i) {
94  if (daughter->getPDGCode() == Const::Klong.getPDGCode()) {
95  if (k_check)
96  B2FATAL("More than one K_L is detected! This module accepts only one K_L in the final state.");
97 
98  StoreObjPtr<ParticleList>().isRequired(daughter->getFullName() + m_recoList);
99  kListName = daughter->getFullName() + m_recoList;
100  k_check = true;
101  } else {
102  StoreObjPtr<ParticleList>().isRequired(daughter->getFullName());
103  newDecayString = newDecayString + daughter->getFullName() + " ";
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  newDecayString = newDecayString + kListName;
111 
112  m_generator = std::make_unique<ParticleGenerator>(newDecayString, m_cutParameter);
113 
115  m_outputList.registerInDataStore(m_listName, flags);
117  m_outputAntiList.registerInDataStore(m_antiListName, flags);
118  }
119 
121 
122 }
123 
125 {
126  m_outputList.create();
127  m_outputList->initialize(m_pdgCode, m_listName);
128 
130  m_outputAntiList.create();
131  m_outputAntiList->initialize(-1 * m_pdgCode, m_antiListName);
132 
133  m_outputList->bindAntiParticleList(*(m_outputAntiList));
134  }
135 
136  m_generator->init();
137 
138  int numberOfCandidates = 0;
139  while (m_generator->loadNext()) {
140 
141  Particle particle = m_generator->getCurrentParticle();
142 
143  bool is_physical = true;
144 
145  const std::vector<Particle*> daughters = particle.getDaughters();
146 
147  if (daughters.size() < 2)
148  B2FATAL("Reconstructing particle as a daughter of a decay with less than 2 daughters!");
149 
150  if (daughters.size() > 3)
151  B2FATAL("Higher multiplicity (>2) missing momentum decays not implemented yet!");
152 
153  int e_check = 0;
154  ROOT::Math::PxPyPzEVector pDaughters;
155  for (auto daughter : daughters) {
156  if (daughter->getPDGCode() != Const::Klong.getPDGCode()) {
157  pDaughters += daughter->get4Vector();
158  e_check = daughter->getArrayIndex() + e_check * 100;
159  }
160  }
161 
162 
163  ROOT::Math::PxPyPzEVector klDaughters;
164  for (auto daughter : daughters) {
165  if (daughter->getPDGCode() == Const::Klong.getPDGCode()) {
166  klDaughters += daughter->get4Vector();
167  if (e_check != daughter->getExtraInfo("permID")) {
168  is_physical = false;
169  }
170  }
171  }
172  double m_b = particle.getPDGMass();
173 
174  ROOT::Math::PxPyPzEVector mom = pDaughters + klDaughters;
175  mom.SetE(TMath::Sqrt(mom.P2() + m_b * m_b));
176  if ((!isnan(mom.P())) && is_physical)
177  particle.set4Vector(mom);
178  if (isnan(mom.P()))
179  is_physical = false;
180 
181  if (!m_cut->check(&particle))
182  continue;
183 
184  if (!is_physical)
185  continue;
186 
187  numberOfCandidates++;
188 
189  if (m_maximumNumberOfCandidates > 0 and numberOfCandidates > m_maximumNumberOfCandidates) {
190  m_outputList->clear();
191  break;
192  }
193 
194  Particle* newParticle = m_particles.appendNew(particle);
195 
196  m_outputList->addParticle(newParticle);
197  newParticle->addExtraInfo("decayModeID", m_decayModeID);
198 
199  } //while
200 
201 } //event
int getPDGCode() const
PDG code.
Definition: Const.h:464
static const ParticleType Klong
K^0_L particle.
Definition: Const.h:669
EStoreFlags
Flags describing behaviours of objects etc.
Definition: DataStore.h:69
@ c_WriteOut
Object/array should be saved by output modules.
Definition: DataStore.h:70
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
Definition: DataStore.h:71
Represents a particle in the DecayDescriptor.
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.
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:84
bool m_isSelfConjugatedParticle
flag that indicates whether an anti-particle mother does not exist and should not be reconstructed as...
int m_maximumNumberOfCandidates
drop all candidates if more candidates than this parameter are produced
std::string m_antiListName
output anti-particle list name
virtual void initialize() override
Initialize the Module.
std::string m_decayString
Input DecayString specifying the decay being reconstructed.
StoreObjPtr< ParticleList > m_outputAntiList
output anti-particle list
StoreArray< Particle > m_particles
StoreArray of Particles.
std::string m_recoList
suffix for input K_L0 list name
StoreObjPtr< ParticleList > m_outputList
output particle list
std::unique_ptr< ParticleGenerator > m_generator
Generates the combinations.
std::unique_ptr< Variable::Cut > m_cut
cut object which performs the cuts
DecayDescriptor m_decaydescriptor
Decay descriptor of the decay being reconstructed.
int m_pdgCode
PDG code of the combined mother particle.
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 setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
Class to store reconstructed particles.
Definition: Particle.h:75
void addExtraInfo(const std::string &name, double value)
Sets the user-defined data of given name to the given value.
Definition: Particle.cc:1337
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:96
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
#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.